package com.yuyou.fn.analyze.service.impl;


import com.alibaba.druid.sql.dialect.postgresql.visitor.PGEvalVisitor;
import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.analyze.constant.TargetTypeEnum;
import com.yuyou.fn.analyze.entity.ClassTarget;
import com.yuyou.fn.analyze.entity.MainAccountTarget;
import com.yuyou.fn.analyze.entity.RefundBonusPerson;
import com.yuyou.fn.analyze.entity.TeacherTarget;
import com.yuyou.fn.analyze.service.*;
import com.yuyou.fn.analyze.vo.*;
import com.yuyou.fn.balance.service.IBalanceTransferService;
import com.yuyou.fn.balance.service.IBalanceWithdrawalService;
import com.yuyou.fn.balance.vo.BalanceTransferQueryVo;
import com.yuyou.fn.balance.vo.BalanceWithdrawalQueryVo;
import com.yuyou.fn.common.condition.annotation.In;
import com.yuyou.fn.common.constant.*;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.*;
import com.yuyou.fn.crm.service.ICustomerResourceService;
import com.yuyou.fn.crm.vo.CustomerResourceQueryVo;
import com.yuyou.fn.educational.entity.*;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.educational.vo.*;
import com.yuyou.fn.platform.entity.AreaTeam;
import com.yuyou.fn.platform.entity.BusTeam;
import com.yuyou.fn.platform.entity.SysResource;
import com.yuyou.fn.platform.permission.DataPermission;
import com.yuyou.fn.platform.service.IAreaTeamService;
import com.yuyou.fn.platform.service.IBusTeamService;
import com.yuyou.fn.platform.service.ISysResourceService;
import com.yuyou.fn.platform.service.ISysUserRoleService;
import com.yuyou.fn.report.entity.ClassLectureDetail;
import com.yuyou.fn.report.entity.MergeStudentRegDetail;
import com.yuyou.fn.report.service.IClassLectureDetailService;
import com.yuyou.fn.report.service.IMergeStudentRegDetailService;
import com.yuyou.fn.report.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.stream.Collectors;


/**
 * ProductTarget 表数据服务层接口实现类
 */
@Service
public class IndexStatistsServiceImpl implements IIndexStatisticsService {

    @Resource
    private ITeacherService teacherService;

    @Resource
    private IPeriodService periodService;

    @Resource
    private IPeriodGradeDateService periodGradeDateService;

    @Resource
    private IMergeStudentRegDetailService mergeStudentRegDetailService;


    @Resource
    private ICourseClassService courseClassService;

    @Resource
    private IClassTargetService classTargetService;

    @Resource
    private IClassLectureDetailService classLectureDetailService;

    @Resource
    private IMainAccountTargetService mainAccountTargetService;

    @Resource
    private IBusTeamService busTeamService;

    @Resource
    private IBaseGradeService baseGradeService;

    @Resource
    private IBaseSubjectService baseSubjectService;

    @Resource
    private ITeacherTargetService teacherTargetService;

    @Resource
    private IAreaTeamService areaTeamService;


    @Resource
    private IExternalRegDetailService externalRegDetailService;

    @Resource
    private IStudentService studentService;

    @Resource
    private ISysResourceService sysResourceService;

    @Resource
    private IStudentRefundService studentRefundService;

    @Resource
    private IBalanceWithdrawalService balanceWithdrawalService;

    @Resource
    private IBalanceTransferService balanceTransferService;

    @Resource
    private ICustomerResourceService customerResourceService;

    @Resource
    private IPeriodSegmentService periodSegmentService;

    @Resource
    private ISysUserRoleService sysUserRoleService;

    @Resource
    private IDataStatisticsService dataStatisticsService;

    @Resource
    private IRefundBonusPersonService refundBonusPersonService;

    private static String[] studentRegDetailColumns={"regId","classId","className", "areaTeamId","busTeamId","busTeamName","gradeId", "gradeName","subjectId","subjectName", "periodId",  "periodName", "teacherId","teacherName", "seniorId", "seniorName", "counselorId", "counselorName","campusId","campusName","studentPhoneNo", "segmentNo", "studentId", "studentName", "createTime","updateTime", "lectureNum","jobNature", "totalAmount","srcTotalAmount","payAmount", "refundAmount","regStatus", "chargingStatus", "studentState", "studentNo", "studentGradeName","payTime"};

    @Override
    public List<NeedDealNumVo> countResourceNeedToDeal(Long areaTeamId, DataPermission dataPermission) {

        Principals.Principal principal=Principals.get();
        if (principal==null){
            throw new BusException("查不到操作人");
        }

        List<NeedDealNumVo> needDealNumVoList=new ArrayList<>();
        List<SysResource> resourceList = sysResourceService.findUserAllResource(principal.id);
        Map<Long,SysResource>  map=BeanUtils.toMap(resourceList,"resourceId");

        if (map.containsKey(SysResourceEnum.STUDENT_REFUND.id)){
            NeedDealNumVo needDealNumVo=new NeedDealNumVo();
            StudentRefundQueryVo studentRefundQueryVo=new StudentRefundQueryVo();
            studentRefundQueryVo.setAreaTeamId(areaTeamId);
            studentRefundQueryVo.setStatus(0);
            Long refundCount=studentRefundService.countStudentRefund(studentRefundQueryVo,dataPermission);
            needDealNumVo.setNum(refundCount.intValue());
            needDealNumVo.setMessage("待处理退费审核");
            needDealNumVo.setUrl(map.get(SysResourceEnum.STUDENT_REFUND.id).getPageUrl()+"?areaTeamId="+areaTeamId+"&status=0");
            needDealNumVoList.add(needDealNumVo);
        }
        if (map.containsKey(SysResourceEnum.WITH_DRAWAL.id)){
            NeedDealNumVo needDealNumVo=new NeedDealNumVo();
            BalanceWithdrawalQueryVo balanceWithdrawalQueryVo=new BalanceWithdrawalQueryVo();
            balanceWithdrawalQueryVo.setAreaTeamId(areaTeamId);
            balanceWithdrawalQueryVo.setStatus(0);
            Long withdrawalCount = balanceWithdrawalService.countBalanceWithdrawalByQuery(balanceWithdrawalQueryVo, dataPermission.getCampusIds());
            needDealNumVo.setNum(withdrawalCount.intValue());
            needDealNumVo.setMessage("待处理提现审核");
            needDealNumVo.setUrl(map.get(SysResourceEnum.WITH_DRAWAL.id).getPageUrl()+"?areaTeamId="+areaTeamId+"&status=0");
            needDealNumVoList.add(needDealNumVo);
        }

        if (map.containsKey(SysResourceEnum.TRANSFER.id)){
            NeedDealNumVo needDealNumVo=new NeedDealNumVo();
            BalanceTransferQueryVo balanceTransferQueryVo=new BalanceTransferQueryVo();
            balanceTransferQueryVo.setAreaTeamId(areaTeamId);
            balanceTransferQueryVo.setStatus(0);
            Long transferCount = balanceTransferService.countBalanceTransferByQuery(balanceTransferQueryVo, dataPermission.getCampusIds());
            needDealNumVo.setNum(transferCount.intValue());
            needDealNumVo.setMessage("待处理转让审核");
            needDealNumVo.setUrl(map.get(SysResourceEnum.TRANSFER.id).getPageUrl()+"?areaTeamId="+areaTeamId+"&status=0");
            needDealNumVoList.add(needDealNumVo);
        }

        if (map.containsKey(SysResourceEnum.LATEN_CUSTOMER.id)){
            NeedDealNumVo needDealNumVo=new NeedDealNumVo();
            CustomerResourceQueryVo customerResourceQueryVo=new CustomerResourceQueryVo();
            customerResourceQueryVo.setAlloStatus(1);
            customerResourceQueryVo.setFollowStatus(0);
            customerResourceQueryVo.setAreaTeamId(areaTeamId);
            Long latentCustomerCount = customerResourceService.countCustomerResourceByQuery(dataPermission, customerResourceQueryVo);
            needDealNumVo.setNum(latentCustomerCount.intValue());
            needDealNumVo.setMessage("可抢占资源");
            needDealNumVo.setUrl(map.get(SysResourceEnum.LATEN_CUSTOMER.id).getPageUrl()+"?areaTeamId="+areaTeamId+"&followStatus=0&alloStatus=1");
            needDealNumVoList.add(needDealNumVo);
        }
        if (map.containsKey(SysResourceEnum.FOLLOW_RESOURCE.id)){
            NeedDealNumVo needDealNumVo=new NeedDealNumVo();
            CustomerResourceQueryVo customerResourceQueryVo=new CustomerResourceQueryVo();
            customerResourceQueryVo.setAreaTeamId(areaTeamId);
            customerResourceQueryVo.setFollowOperatorId(principal.id);
            Long unFollowResourceCount = customerResourceService.countCanVisitCustomerResourceByQuery(dataPermission, customerResourceQueryVo);
            needDealNumVo.setNum(unFollowResourceCount.intValue());
            needDealNumVo.setMessage("待跟进资源");
            needDealNumVo.setUrl(map.get(SysResourceEnum.FOLLOW_RESOURCE.id).getPageUrl()+"?areaTeamId="+areaTeamId);
            needDealNumVoList.add(needDealNumVo);
        }

        if (map.containsKey(SysResourceEnum.TIME_OUT_RESOURCE.id)){
            NeedDealNumVo needDealNumVo=new NeedDealNumVo();
            CustomerResourceQueryVo customerResourceQueryVo=new CustomerResourceQueryVo();
            customerResourceQueryVo.setTimeoutStatus(1);
            customerResourceQueryVo.setFollowStatus(0);
            customerResourceQueryVo.setAreaTeamId(areaTeamId);
            Long timeOutResourceCount = customerResourceService.countCustomerResourceByQuery(dataPermission, customerResourceQueryVo);
            needDealNumVo.setNum(timeOutResourceCount.intValue());
            needDealNumVo.setMessage("超时未抢占资源");
            needDealNumVo.setUrl(map.get(SysResourceEnum.TIME_OUT_RESOURCE.id).getPageUrl()+"?areaTeamId="+areaTeamId+"&timeoutStatus=1&followStatus=0");
            needDealNumVoList.add(needDealNumVo);
        }

        return needDealNumVoList;
    }

    @Override
    public DataCountVo findDataCount(String year,DataPermission dataPermission,Long areaTeamId,List<Long> periodIds,List<Long> gradeIds) {
        DataCountVo dataCountVo=new DataCountVo();
        Principals.Principal principal=Principals.get();
        if (principal==null){
            throw new BusException("查不到操作人");
        }
        if (dataPermission==null || Utils.checkListEmpty(dataPermission.getBusTeamIds()) ||areaTeamId==null || Utils.checkListEmpty(periodIds)  ){
            return dataCountVo;
        }
        String urlParams= "?year="+year+"&areaTeamId="+areaTeamId+"&periodIds=["+StringUtils.join(periodIds,",")+"]&gradeIds=["+StringUtils.join(gradeIds,",")+"]";
        List<SysResource> resourceList = sysResourceService.findUserAllResource(principal.id);
        Map<Long,SysResource>  map=BeanUtils.toMap(resourceList,"resourceId");

        if(map.containsKey(SysResourceEnum.BUSINESS_SITUATION.id) || map.containsKey(SysResourceEnum.FULL_CLASS_RATE.id) || map.containsKey(SysResourceEnum.ONLINE_LIST.id)){
            SysResource businessSituation=map.get(SysResourceEnum.BUSINESS_SITUATION.id);
            SysResource fullClassRate=map.get(SysResourceEnum.FULL_CLASS_RATE.id);
            SysResource onlineList=map.get(SysResourceEnum.ONLINE_LIST.id);

            PeriodQueryRegVo periodQueryRegVo=new PeriodQueryRegVo();
            periodQueryRegVo.setRegStatuses(Arrays.asList(0,3));
            periodQueryRegVo.setGradeIds(gradeIds);
            periodQueryRegVo.setBusTeamIds(dataPermission.getBusTeamIds());
            periodQueryRegVo.setAreaTeamId(areaTeamId);
            List<MergeStudentRegDetail> mergeStudentRegDetailList =mergeStudentRegDetailService.findByAreaTeamIdPeriodIds(areaTeamId,periodIds,periodQueryRegVo,"classId","regFrom","payAmount","regId","studentId","refundAmount","lectureNum","studentState","regStatus","chargingStatus");

            if (mergeStudentRegDetailList !=null){
                if (businessSituation!=null){
                    dataCountVo.setAmountUrl(businessSituation.getPageUrl()+urlParams);
                    dataCountVo.setBranchUrl(businessSituation.getPageUrl()+urlParams);
                    for (MergeStudentRegDetail mergeStudentRegDetail : mergeStudentRegDetailList){
                        if (mergeStudentRegDetail.getStudentState()==null){
                            continue;
                        }
                        dataCountVo.setAmount(dataCountVo.getAmount().add(mergeStudentRegDetail.getPayAmount().subtract(mergeStudentRegDetail.getRefundAmount() == null ? BigDecimal.ZERO : mergeStudentRegDetail.getRefundAmount())));
                        if (mergeStudentRegDetail.getRegStatus() == 0) {
                            Integer studentState = mergeStudentRegDetail.getStudentState();
                            if (studentState == 0) {
                                dataCountVo.setNewBranchNum(dataCountVo.getNewBranchNum() + 1);
                            } else if (studentState == 1) {
                                dataCountVo.setOldBranchNum(dataCountVo.getOldBranchNum() + 1);
                            } else if (studentState == 2) {
                                dataCountVo.setSeqStepBranchNum(dataCountVo.getSeqStepBranchNum() + 1);
                            }
                        }
                    }
                }

                if (onlineList!=null){
                    for (MergeStudentRegDetail mergeStudentRegDetail : mergeStudentRegDetailList){
                        Integer regFrom= mergeStudentRegDetail.getRegFrom();
                        if (mergeStudentRegDetail.getChargingStatus()!=2 || mergeStudentRegDetail.getRegStatus()!=0 || mergeStudentRegDetail.getStudentState()==null){
                            continue;
                        }
                        dataCountVo.setAllRegNum(dataCountVo.getAllRegNum()+1);
                        if (regFrom!=null && regFrom==1){
                            dataCountVo.setOnlineBranchNum(dataCountVo.getOnlineBranchNum()+1);
                        }
                    }
                    dataCountVo.setOnlineUrl(onlineList.getPageUrl()+urlParams);
                    dataCountVo.setOnlineRate(Utils.getPercent(dataCountVo.getOnlineBranchNum().toString(),dataCountVo.getAllRegNum().toString(),2));
                }
                if (fullClassRate!=null){
                    List<PeriodSegment> periodSegmentList=periodSegmentService.findByPeriodSegmentListByPeriodIds(periodIds);
                    Map<Long,Map<Integer,PeriodSegment>> periodSegmentMap=periodSegmentService.periodSegmentToMapGroup(periodSegmentList);

                    List<CourseClass> courseClassList=courseClassService.findListByBusTeamIdsPeriodIdsGradeIdsStatuses(dataPermission.getBusTeamIds(),periodIds,gradeIds,Arrays.asList(1,3),"classId","quota");
                    Map<Long, CourseClass> classMap = BeanUtils.toMap(courseClassList, "classId");

                    for (CourseClass courseClass:courseClassList){
                        dataCountVo.setTotalQuota(dataCountVo.getTotalQuota()+(courseClass.getQuota()==null?0:courseClass.getQuota()));
                    }
                    for (MergeStudentRegDetail mergeStudentRegDetail : mergeStudentRegDetailList){
                        if (!mergeStudentRegDetailService.checkClassBigEffectiveLectureNum(mergeStudentRegDetail.getLectureNum(),mergeStudentRegDetail.getSegmentNo(),mergeStudentRegDetail.getPeriodId(),periodSegmentMap)){
                            continue;
                        }
                        if (classMap.containsKey(mergeStudentRegDetail.getClassId()) && mergeStudentRegDetail.getChargingStatus()==2 && mergeStudentRegDetail.getStudentState()!=null && mergeStudentRegDetail.getRegStatus()==0){
                            dataCountVo.setBigLectureRegNum(dataCountVo.getBigLectureRegNum()+1);
                        }
                    }
                    dataCountVo.setFullClassRateUrl(fullClassRate.getPageUrl()+urlParams);
                    dataCountVo.setFullClassRate(Utils.getPercent(dataCountVo.getBigLectureRegNum().toString(),dataCountVo.getTotalQuota().toString(),2));
                }
            }
        }
        return dataCountVo;
    }

    @Override
    public CampusSeqStepRateVo findCampusSeqStepRate(String year,Long areaTeamId,DataPermission dataPermission,List<Long> periodIds,List<Long> gradeIds) {
        Principals.Principal principal=Principals.get();
        if (principal==null){
            throw new BusException("查不到操作人");
        }

        CampusSeqStepRateVo campusSeqStepRateVo=new CampusSeqStepRateVo();
        if (dataPermission==null || Utils.checkListEmpty(dataPermission.getBusTeamIds()) ||areaTeamId==null || Utils.checkListEmpty(periodIds)  ){
            return campusSeqStepRateVo;
        }
        String urlParams= "?year="+year+"&areaTeamId="+areaTeamId+"&periodIds=["+StringUtils.join(periodIds,",")+"]&gradeIds=["+StringUtils.join(gradeIds,",")+"]";
        List<SysResource> resourceList = sysResourceService.findUserAllResource(principal.id);
        Map<Long,SysResource>  map=BeanUtils.toMap(resourceList,"resourceId");
        if (!map.containsKey(SysResourceEnum.GRADE_COMPLETION.id)){
            return campusSeqStepRateVo;
        }

        PeriodSeqStepSituationVo periodSeqStepSituationVo=periodService.findPeriodSeqStepSituation(periodIds);

        Map<Long,List<Long>> seqMap=periodSeqStepSituationVo.getSeqMap();
        Map<Long,List<Long>> stepMap=periodSeqStepSituationVo.getStepMap();
        List<Long> seqStepList=periodSeqStepSituationVo.getSeqStepList();
        Map<Long,Map<Integer,PeriodSegment>> periodSegmentMap=periodSeqStepSituationVo.getPeriodSegmentMap();
        List<Long> allPeriodIds=periodSeqStepSituationVo.getAllPeriodIds();

        PeriodQueryRegVo periodQueryRegVo=new PeriodQueryRegVo();
        periodQueryRegVo.setAreaTeamId(areaTeamId);
        periodQueryRegVo.setBusTeamIds(dataPermission.getBusTeamIds());
        periodQueryRegVo.setPeriodIds(periodIds);
        periodQueryRegVo.setGradeIds(gradeIds);
        //periodQueryRegVo.setLectureNum(5);
        periodQueryRegVo.setChargingStatus(2);
        periodQueryRegVo.setRegStatus(0);
        RegRelativceQueryVo regRelativceQueryVo=new RegRelativceQueryVo();
        regRelativceQueryVo.setNeedSameSubject(1);
        //regRelativceQueryVo.setBigRecordLectureNum(5);
        regRelativceQueryVo.setPeriodIds(seqStepList);
        List<RegRelativeVo> regRelativeVoList=mergeStudentRegDetailService.queryRegRelative(periodQueryRegVo,regRelativceQueryVo);
        regRelativeVoList=mergeStudentRegDetailService.filterListByEffectiveLectureNum(regRelativeVoList,periodSegmentMap);
        regRelativeVoList=mergeStudentRegDetailService.filterListByReportConfig(allPeriodIds,regRelativeVoList, ReportResourceEnum.校区续读.id);

        Map<Long,Integer> recordReg=new HashMap<>();
        for (RegRelativeVo regRelativeVo:regRelativeVoList){

            Long regId=regRelativeVo.getRegId();
            Long relativePeriodId=regRelativeVo.getRelativePeriodId();

            Long periodId=regRelativeVo.getPeriodId();
            List<Long> seqIdList=seqMap.get(periodId);
            List<Long> stepIdList=stepMap.get(periodId);

            if (!recordReg.containsKey(regId)){
                campusSeqStepRateVo.setNowNum(campusSeqStepRateVo.getNowNum()+1);
                recordReg.put(regId,1);
            }

            if (regRelativeVo.getRelativeRegId()==null) {
                continue;
            }
            if (seqIdList!=null && seqIdList.contains(relativePeriodId)){
                campusSeqStepRateVo.setSeqNum(campusSeqStepRateVo.getSeqNum()+1);
            }
            if (stepIdList!=null && stepIdList.contains(relativePeriodId)){
                campusSeqStepRateVo.setStepNum(campusSeqStepRateVo.getStepNum()+1);
            }
        }
        campusSeqStepRateVo.setSeqRate(Utils.getPercent(campusSeqStepRateVo.getSeqNum().toString(),campusSeqStepRateVo.getNowNum().toString(),2));
        campusSeqStepRateVo.setStepRate(Utils.getPercent(campusSeqStepRateVo.getStepNum().toString(),campusSeqStepRateVo.getNowNum().toString(),2));
        campusSeqStepRateVo.setCampusSeqStepUrl(map.get(SysResourceEnum.GRADE_COMPLETION.id).getPageUrl()+urlParams);
        return campusSeqStepRateVo;
    }

    @Override
    public Page<CounselorBranchBonusVo> findCounselorBranchBonusPage(List<Long> busTeamIds, PeriodQueryRegVo periodQueryRegVo, DataPermission dataPermission, TeacherQueryVo teacherQueryVo, List<Long> periodIds, int pageNo, int pageSize, Integer bigLectureNum) {
        Page<Teacher> teacherPage = teacherService.findTeacherInBusTeamListOrNullForPage(dataPermission,teacherQueryVo, busTeamIds, pageNo, pageSize);
        List<Period> periodList = periodService.findByIds(periodIds);
        Page<CounselorBranchBonusVo> counselorBranchBonusVoPage = Utils.newPage(teacherPage);
        List<Teacher> teacherList = teacherPage.getRecords();
        if (teacherList != null && teacherList.size() > 0) {
            List<Long> teacherIdList = BeanUtils.toList(teacherList, "teacherId");

            List<MergeStudentRegDetail> mergeStudentRegDetailList =mergeStudentRegDetailService.findByCounselorIdsPeriodIdsStates(teacherIdList,periodIds,Arrays.asList(0,1),periodQueryRegVo,studentRegDetailColumns);
            mergeStudentRegDetailList=mergeStudentRegDetailService.filteRegByReportConfig(periodIds,mergeStudentRegDetailList,ReportResourceEnum.薪酬咨询师科数.id);
            counselorBranchBonusVoPage.setRecords(toCounselorBranchBonusList(teacherList,periodList, mergeStudentRegDetailList,bigLectureNum));
        }
        return counselorBranchBonusVoPage;
    }

    @Override
    public SXSSFWorkbook exportCounselorBranchBonus( List<Long> busTeamIds, PeriodQueryRegVo periodQueryRegVo, DataPermission dataPermission, TeacherQueryVo teacherQueryVo, List<Long> periodIds, Integer bigLectureNum) {

        Page<CounselorBranchBonusVo> counselorBranchBonusVoPage=this.findCounselorBranchBonusPage(busTeamIds,periodQueryRegVo,dataPermission,teacherQueryVo,periodIds,1,10000,bigLectureNum);
        List<Long> teacherIds = BeanUtils.toList(counselorBranchBonusVoPage.getRecords(), "teacherId");
        List<Teacher> teacherList=teacherService.findByIds(teacherIds);
        Map<Long,Teacher> teacherMap=BeanUtils.toMap(teacherList,"teacherId");

        return counselorCompletionRate2excel(counselorBranchBonusVoPage.getRecords(),teacherMap,sysUserRoleService.showIdNoByCheckRoleNames(Principals.get().id));
    }

    public static SXSSFWorkbook counselorCompletionRate2excel(List<CounselorBranchBonusVo> counselorBranchBonusVoList,Map<Long,Teacher> teacherMap,Boolean showIdNo) {


        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("咨询师新老生统计");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"区域", "业务组", "期数", "咨询师", "身份证","咨询师职能","新生科数(小于6讲)", "新生科数(大于等于6讲)", "老生科数(小于6讲)", "老生科数(大于等于6讲)"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }

        SXSSFSheet detailSheet = excel.createSheet("新老生科数明细");
        SXSSFRow detailFirstRow = detailSheet.createRow(0);
        String[] detailTitles = new String[]{"业务组", "期数", "报读校区", "咨询师", "咨询师职能", "学生姓名", "学生电话号码","报读年级","生源类型","学号", "年级", "6讲（含）以上", "6讲以下科数"};
        for (int i = 0; i < detailTitles.length; i++) {
            detailFirstRow.createCell(i).setCellValue(detailTitles[i]);
        }
        int detailRowNum = 1;
        int rowNum = 1;
        for (CounselorBranchBonusVo counselorBranchBonusVo : counselorBranchBonusVoList) {
            int cellNum = 0;
            Teacher teacher=teacherMap.get(counselorBranchBonusVo.getTeacherId());

            SXSSFRow row = sheet.createRow(rowNum);
            rowNum++;

            SXSSFCell cell = row.createCell(cellNum);
            cell.setCellValue(counselorBranchBonusVo.getAreaTeamName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(counselorBranchBonusVo.getBusTeamName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(counselorBranchBonusVo.getPeriodName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(counselorBranchBonusVo.getTeacherName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(StringUtils.defaultString(showIdNo?teacher.getIdNo():""));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(EnumUtils.getName(AccessTypeEnum.values() ,teacher==null?null:teacher.getAccessType()));
            cellNum++;


            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(counselorBranchBonusVo.getLessRealNewStudentNum());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(counselorBranchBonusVo.getBigRealNewStudentNum());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(counselorBranchBonusVo.getLessRealOldStudentNum());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(counselorBranchBonusVo.getBigRealOldStudentNum());
            cellNum++;
            if (counselorBranchBonusVo.getCounselorRegDetailList() != null) {
                for (CounselorRegDetail counselorRegDetail : counselorBranchBonusVo.getCounselorRegDetailList()) {
                    int detailCellNum = 0;
                    SXSSFRow detailRow = detailSheet.createRow(detailRowNum++);

                    SXSSFCell detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(counselorRegDetail.getBusTeamName());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(counselorRegDetail.getPeriodName());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(counselorRegDetail.getCampusName());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(counselorRegDetail.getTeacherName());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(EnumUtils.getName(AccessTypeEnum.values() ,teacher==null?null:teacher.getAccessType()));

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(counselorRegDetail.getStudentName());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(counselorRegDetail.getStudentPhoneNo());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(counselorRegDetail.getGradeName());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(counselorRegDetail.getRelativeType()==0?"新生":"老生");

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(counselorRegDetail.getStudentNo());


                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(counselorRegDetail.getStudentGradeName());


                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellType(CellType.NUMERIC);
                    detailCell.setCellValue(counselorRegDetail.getBigLectureNum());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellType(CellType.NUMERIC);
                    detailCell.setCellValue(counselorRegDetail.getLessLectureNum());
                }
            }

        }
        return excel;
    }


    @Override
    public Page<SeniorBranchBonusVo> findSeniorBranchBonusPage(List<Long> busTeamIds, RegRelativceQueryVo regRelativceQueryVo, DataPermission dataPermission, TeacherQueryVo teacherQueryVo, List<Long> periodIds, int pageNo, int pageSize, Integer bigLectureNum) {
        regRelativceQueryVo.setHaveRelative(1);
        Page<Teacher> teacherPage = teacherService.findTeacherByBusTeamListForPage(teacherQueryVo, busTeamIds, pageNo, pageSize);
        List<Period> periodList = periodService.findByIds(periodIds);
        Map<Long,List<Long>> seqMap=new HashMap<>();
        Map<Long,List<Long>> stepMap=new HashMap<>();
        List<Long> seqStepList=new ArrayList<>();
        for (Period period:periodList){
            Long periodId=period.getPeriodId();
            Integer periodNo=period.getPeriodNo();
            List<Period> seqStepPeriod = periodService.findNextByPeriodId(periodId, 2);
            List<Long> useSeqPeriodIds=new ArrayList<>(seqStepPeriod==null?0:seqStepPeriod.size());
            List<Long> useStepPeriodIds=new ArrayList<>(seqStepPeriod==null?0:seqStepPeriod.size());
            for (Period temp:seqStepPeriod){
                if (temp.getPeriodNo()-1==periodNo){
                    useSeqPeriodIds.add(temp.getPeriodId());
                }
                if (temp.getPeriodNo()-2==periodNo){
                    useStepPeriodIds.add(temp.getPeriodId());
                }
            }
            seqStepList.addAll(useSeqPeriodIds);
            seqStepList.addAll(useStepPeriodIds);
            seqMap.put(periodId,useSeqPeriodIds);
            stepMap.put(periodId,useStepPeriodIds);
        }

        Page<SeniorBranchBonusVo> seniorBranchBonusVoPage = Utils.newPage(teacherPage);
        List<SeniorBranchBonusVo> seniorBranchBonusVoList=new ArrayList<>();
        List<Teacher> teacherList = teacherPage.getRecords();
        if (teacherList != null && teacherList.size() > 0) {
            List<Long> teacherIdList = BeanUtils.toList(teacherList, "teacherId");
            PeriodQueryRegVo periodQueryRegVo=new PeriodQueryRegVo();
            periodQueryRegVo.setSeniorIds(teacherIdList);
            periodQueryRegVo.setPeriodIds(periodIds);
            regRelativceQueryVo.setPeriodIds(seqStepList);
            List<Long> allPeriodIds=new ArrayList<>();
            allPeriodIds.addAll(periodIds);
            allPeriodIds.addAll(seqStepList);
            List<RegRelativeVo> regRelativeVoList=mergeStudentRegDetailService.queryRegRelative(periodQueryRegVo,regRelativceQueryVo);
            regRelativeVoList=mergeStudentRegDetailService.filterListByReportConfig(allPeriodIds,regRelativeVoList,ReportResourceEnum.薪酬班主任续读.id);
            Map<Long,List<RegRelativeVo>> regRelativeVoMap=BeanUtils.toGroup(regRelativeVoList,"seniorId");
            for (Teacher teacher:teacherList){
                Long teacherId=teacher.getTeacherId();
                List<RegRelativeVo> regRelativeVoTeacherList=regRelativeVoMap.get(teacherId);
                Map<Long,List<RegRelativeVo>> regRelativeVoTeacherMap=BeanUtils.toGroup(regRelativeVoTeacherList,"periodId");
                for (Period period:periodList){
                    Map<String, SeniorRegDetail> map = new HashMap<>();
                    Map<Long,Integer> recordMap=new HashMap<>();
                    SeniorBranchBonusVo seniorBranchBonusVo = new SeniorBranchBonusVo();
                    seniorBranchBonusVo.setAreaTeamId(teacher.getAreaTeamId());
                    seniorBranchBonusVo.setAreaTeamName(teacher.getAreaTeamName());
                    seniorBranchBonusVo.setBusTeamId(teacher.getBusTeamId());
                    seniorBranchBonusVo.setBusTeamName(teacher.getBusTeamName());
                    seniorBranchBonusVo.setPeriodId(period.getPeriodId());
                    seniorBranchBonusVo.setPeriodName(period.getPeriodName());
                    seniorBranchBonusVo.setTeacherId(teacher.getTeacherId());
                    seniorBranchBonusVo.setTeacherName(teacher.getTeacherName());
                    Long periodId=period.getPeriodId();
                    List<Long> seqIdList=seqMap.get(periodId);
                    List<Long> stepIdList=stepMap.get(periodId);
                    List<RegRelativeVo> regRelativeVoTeacherPeriodList=regRelativeVoTeacherMap.get(periodId);
                    if (regRelativeVoTeacherPeriodList!=null){
                        for (RegRelativeVo regRelativeVo:regRelativeVoTeacherPeriodList){
                            Long busTeamId=regRelativeVo.getBusTeamId();
                            Long relativePeriodId=regRelativeVo.getRelativePeriodId();
                            Long relativeRegId=regRelativeVo.getRelativeRegId();
                            Integer relativeLectureNum=regRelativeVo.getRelativeLectureNum();
                            Long studentId=regRelativeVo.getStudentId();
                            String key=busTeamId+"_"+studentId;
                            SeniorRegDetail seniorRegDetail=map.get(key);
                            if (seniorRegDetail==null){
                                seniorRegDetail=new SeniorRegDetail();
                                seniorRegDetail.setBusTeamId(regRelativeVo.getBusTeamId());
                                seniorRegDetail.setBusTeamName(regRelativeVo.getBusTeamName());
                                seniorRegDetail.setPeriodId(period.getPeriodId());
                                seniorRegDetail.setPeriodName(period.getPeriodName());
                                seniorRegDetail.setTeacherId(teacher.getTeacherId());
                                seniorRegDetail.setTeacherName(teacher.getTeacherName());
                                seniorRegDetail.setStudentId(studentId);
                                seniorRegDetail.setStudentName(regRelativeVo.getStudentName());
                                seniorRegDetail.setStudentPhoneNo(regRelativeVo.getStudentPhoneNo());
                                seniorRegDetail.setStudentNo(regRelativeVo.getStudentNo());
                                seniorRegDetail.setStudentGradeName(regRelativeVo.getStudentGradeName());
                                map.put(key,seniorRegDetail);
                            }
                            if (relativeRegId==null){
                                continue;
                            }
                            String periodSeniorKey=regRelativeVo.getPeriodId()+"_"+regRelativeVo.getSeniorId();
                            if (!recordMap.containsKey(relativeRegId) && seqIdList!=null && seqIdList.contains(relativePeriodId) ){
                                if (relativeLectureNum>bigLectureNum){
                                    seniorBranchBonusVo.setBigSeqStudentNum(seniorBranchBonusVo.getBigSeqStudentNum()+1);
                                    seniorRegDetail.setBigSeqNum(seniorRegDetail.getBigSeqNum()+1);
                                }else {
                                    seniorBranchBonusVo.setLessSeqStudentNum(seniorBranchBonusVo.getLessSeqStudentNum()+1);
                                    seniorRegDetail.setLessSeqNum(seniorRegDetail.getLessSeqNum()+1);
                                }
                                recordMap.put(relativeRegId,1);
                            }
                            if (!recordMap.containsKey(relativeRegId) && stepIdList!=null && stepIdList.contains(relativePeriodId)  ){
                                if (relativeLectureNum>bigLectureNum){
                                    seniorBranchBonusVo.setBigStepStudentNum(seniorBranchBonusVo.getBigStepStudentNum()+1);
                                    seniorRegDetail.setBigStepNum(seniorRegDetail.getBigStepNum()+1);
                                }else {
                                    seniorBranchBonusVo.setLessStepStudentNum(seniorBranchBonusVo.getLessStepStudentNum()+1);
                                    seniorRegDetail.setLessStepNum(seniorRegDetail.getLessStepNum()+1);
                                }
                                recordMap.put(relativeRegId,1);
                            }
                        }
                    }
                    Collection<SeniorRegDetail> seniorRegDetailCollection=map.values();
                    List<SeniorRegDetail> seniorRegDetailList=new ArrayList<>(seniorRegDetailCollection);
                    seniorBranchBonusVo.setSeniorRegDetailList(seniorRegDetailList);
                    seniorBranchBonusVoList.add(seniorBranchBonusVo);
                }
            }
            seniorBranchBonusVoPage.setRecords(seniorBranchBonusVoList);
        }
        return seniorBranchBonusVoPage;
    }

    @Override
    public SXSSFWorkbook exportSeniorBranchBonus(List<Long> busTeamIds,List<Integer> relativeTypes, String teacherType, RegRelativceQueryVo regRelativceQueryVo, DataPermission dataPermission, TeacherQueryVo teacherQueryVo, List<Long> periodIds,  Integer bigLectureNum){

        Page<SeniorBranchBonusVo> seniorBranchBonusVoPage=this.findSeniorBranchBonusPage(busTeamIds,regRelativceQueryVo,dataPermission,teacherQueryVo,periodIds,1,10000,bigLectureNum);
        List<Long> teacherIds = Utils.removeDuplicate(BeanUtils.toList(seniorBranchBonusVoPage.getRecords(), "teacherId"));
        List<Teacher> teacherList=teacherService.findByIds(teacherIds);
        Map<Long,Teacher> teacherMap=BeanUtils.toMap(teacherList,"teacherId");
        return seniorBranch2excel(seniorBranchBonusVoPage.getRecords(),teacherMap,sysUserRoleService.showIdNoByCheckRoleNames(Principals.get().id));
    }

    public static SXSSFWorkbook seniorBranch2excel(List<SeniorBranchBonusVo> seniorBranchBonusVoList, Map<Long,Teacher> teacherMap,Boolean showIdNo) {
        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("班主任续读（奖金指标）");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"区域", "业务组", "期数", "班主任", "身份证","顺期科数(小于6讲)", "顺期科数(大于等于6讲)", "跨期科数(小于6讲)", "跨期科数(大于等于6讲)"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }

        SXSSFSheet detailSheet = excel.createSheet("班主任科数明细");
        SXSSFRow detailFirstRow = detailSheet.createRow(0);
        String[] detailTitles = new String[]{"业务组", "期数",  "班主任", "学生姓名", "学生电话号码","学号", "年级", "顺期科数(小于6讲)", "顺期科数(大于等于6讲)", "跨期科数(小于6讲)", "跨期科数(大于等于6讲)"};
        for (int i = 0; i < detailTitles.length; i++) {
            detailFirstRow.createCell(i).setCellValue(detailTitles[i]);
        }
        int detailRowNum = 1;
        int rowNum = 1;
        for (SeniorBranchBonusVo seniorBranchBonusVo : seniorBranchBonusVoList) {
            int cellNum = 0;
            Teacher teacher=teacherMap.get(seniorBranchBonusVo.getTeacherId())==null?new Teacher():teacherMap.get(seniorBranchBonusVo.getTeacherId());
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(seniorBranchBonusVo.getAreaTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(seniorBranchBonusVo.getBusTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(seniorBranchBonusVo.getPeriodName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(seniorBranchBonusVo.getTeacherName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(StringUtils.defaultString(showIdNo?teacher.getIdNo():""));

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(seniorBranchBonusVo.getLessSeqStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(seniorBranchBonusVo.getBigSeqStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(seniorBranchBonusVo.getLessStepStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(seniorBranchBonusVo.getBigStepStudentNum());

            if (seniorBranchBonusVo.getSeniorRegDetailList() != null) {
                for (SeniorRegDetail seniorRegDetail : seniorBranchBonusVo.getSeniorRegDetailList()) {
                    int detailCellNum = 0;
                    SXSSFRow detailRow = detailSheet.createRow(detailRowNum++);

                    SXSSFCell detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(seniorRegDetail.getBusTeamName());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(seniorRegDetail.getPeriodName());



                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(seniorRegDetail.getTeacherName());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(seniorRegDetail.getStudentName());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(seniorRegDetail.getStudentPhoneNo());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(seniorRegDetail.getStudentNo());


                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellValue(seniorRegDetail.getStudentGradeName());


                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellType(CellType.NUMERIC);
                    detailCell.setCellValue(seniorRegDetail.getLessSeqNum());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellType(CellType.NUMERIC);
                    detailCell.setCellValue(seniorRegDetail.getBigSeqNum());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellType(CellType.NUMERIC);
                    detailCell.setCellValue(seniorRegDetail.getLessStepNum());

                    detailCell = detailRow.createCell(detailCellNum++);
                    detailCell.setCellType(CellType.NUMERIC);
                    detailCell.setCellValue(seniorRegDetail.getBigStepNum());
                }
            }

        }
        return excel;
    }

    @Override
    public Page<ClassComletionRateVo> findClassComletionRateVoPage(List<Long> periodIds, List<Long> busTeamIds, List<Long> gradeIds, CourseClassQueryVo courseClassQueryVo, DataPermission dataPermission, int pageNo, int pageSize, RegRelativceQueryVo regRelativceQueryVo) {
        if (courseClassQueryVo.getAreaTeamId() == null) {
            throw new BusException("区域必选");
        }
        if (regRelativceQueryVo.getEndRecordRegTime()!=null){
            regRelativceQueryVo.setEndRecordRegTime(TimeUtils.changeOneDateLastTime(regRelativceQueryVo.getEndRecordRegTime()));
        }
        if (regRelativceQueryVo.getEndPayTime()!=null){
            regRelativceQueryVo.setEndPayTime(TimeUtils.changeOneDateLastTime(regRelativceQueryVo.getEndPayTime()));
        }

        regRelativceQueryVo.setRecordChargingStatus(2);
        courseClassQueryVo.setStatusList(Arrays.asList(1,3));
        PeriodSeqStepSituationVo periodSeqStepSituationVo=periodService.findPeriodSeqStepSituation(periodIds);
        List<Period> periodList = periodSeqStepSituationVo.getPeriodList();
        Map<Long,List<Long>> seqMap=periodSeqStepSituationVo.getSeqMap();
        Map<Long,List<Long>> stepMap=periodSeqStepSituationVo.getStepMap();
        List<Long> seqStepList=periodSeqStepSituationVo.getSeqStepList();
        Map<Long,Map<Integer,PeriodSegment>> periodSegmentMap=periodSeqStepSituationVo.getPeriodSegmentMap();
        List<Long> allPeriodIds = periodSeqStepSituationVo.getAllPeriodIds();
        List<Long> subjectIds=courseClassQueryVo.getSubjectId()!=null?Arrays.asList(courseClassQueryVo.getSubjectId()):Utils.isEmpty(courseClassQueryVo.getSubjectIds())?new ArrayList<>():courseClassQueryVo.getSubjectIds();
        PerimissionTypeListVo perimissionTypeListVo = this.checkAndFillDataPerssion(dataPermission, courseClassQueryVo.getAreaTeamId(), busTeamIds, gradeIds, subjectIds);
        busTeamIds=perimissionTypeListVo.getBusTeamIds();
        gradeIds=perimissionTypeListVo.getGradeIds();
        subjectIds=perimissionTypeListVo.getSubjectIds();
        courseClassQueryVo.setSubjectId(null);
        courseClassQueryVo.setSubjectIds(subjectIds);

        Page<CourseClass> page = courseClassService.findByQueryForPage(periodIds,busTeamIds,gradeIds,courseClassQueryVo, pageNo, pageSize);
        Page<ClassComletionRateVo> classComletionRateVoPage = Utils.newPage(page);
        List<CourseClass> courseClassList = page.getRecords();
        List<Long> classIds = BeanUtils.toList(courseClassList, "classId");

        if (courseClassList != null && courseClassList.size()>0) {
            regRelativceQueryVo.setPeriodIds(seqStepList);
            regRelativceQueryVo.setNeedSameSubject(1);
            List<Callable<List<RegRelativeVo>>> taskList  = new ArrayList<>();
            int size=100;
            int count=(int)Math.ceil((double)classIds.size()/size);
            for (int i = 1; i <= count; i++) {
                PeriodQueryRegVo periodQueryRegVo = new PeriodQueryRegVo();
                int end=(i*size)>classIds.size()?classIds.size():(i*size);
                periodQueryRegVo.setClassIds(classIds.subList((i - 1) * size, end));
                periodQueryRegVo.setRegStatus(0);
                periodQueryRegVo.setChargingStatus(2);
                taskList.add(new Callable<List<RegRelativeVo>>() {
                    @Override
                    public List<RegRelativeVo> call() throws Exception {
                        List<RegRelativeVo> temp = mergeStudentRegDetailService.queryRegRelative(periodQueryRegVo, regRelativceQueryVo);
                        return temp;
                    }
                });
            }
            List<RegRelativeVo> regRelativeVoList = new ArrayList<>();
            try{
                List<Future<List<RegRelativeVo>>> futures = Threads.invokeAll(taskList);

                for(Future<List<RegRelativeVo>> f : futures ){
                    if (!Utils.isEmpty(f.get())){
                        regRelativeVoList.addAll(f.get());
                    }
                }
            }catch (Exception e){
                throw new BusException(e.getMessage());
            }

            regRelativeVoList=mergeStudentRegDetailService.filterListByEffectiveLectureNum(regRelativeVoList,periodSegmentMap);
            regRelativeVoList=mergeStudentRegDetailService.filterListByReportConfig(allPeriodIds,regRelativeVoList,ReportResourceEnum.薪酬教师续读.id);

            Map<Long, List<RegRelativeVo>> relativeVoMap = BeanUtils.toGroup(regRelativeVoList, "classId");
            Map<Long,List<CourseClass>> map=BeanUtils.toGroup(courseClassList,"periodId");
            List<ClassComletionRateVo> classComletionRateVoList = new ArrayList<ClassComletionRateVo>(courseClassList.size());
            List<ClassTarget> classTargetList  = classTargetService.findByIds(classIds);
            Map<Long, ClassTarget> classTargetMap = BeanUtils.toMap(classTargetList, "classId");
            for (Period period:periodList){
                Long periodId=period.getPeriodId();
                List<Long> seqIdList=seqMap.get(periodId);
                List<Long> stepIdList=stepMap.get(periodId);
                List<CourseClass> onePeriodCourseClassList=map.get(periodId);
                if (onePeriodCourseClassList==null){
                    continue;
                }
                for (CourseClass courseClass:onePeriodCourseClassList){
                    Map<Long,ClassComletionDetailVo> classComletionDetailVoMap=new HashMap<>();
                    Map<String,Integer> recordMap=new HashMap<>();
                    Long classId=courseClass.getClassId();
                    ClassComletionRateVo classComletionRateVo=new ClassComletionRateVo();
                    BeanUtils.springCopyProperties(classComletionRateVo, courseClass);
                    ClassTarget classTarget=classTargetMap.get(classId);
                    List<RegRelativeVo> classRegRelativeList=relativeVoMap.get(classId);
                    if (classTarget != null) {
                        classComletionRateVo.setSequentialTargetRate(classTarget.getSequentialTargetRate());
                        classComletionRateVo.setStepTargetRate(classTarget.getStepTargetRate());
                    }
                    if (classRegRelativeList!=null){
                        for (RegRelativeVo regRelativeVo:classRegRelativeList){

                            Long regId=regRelativeVo.getRegId();
                            Long relativeRegId=regRelativeVo.getRelativeRegId();
                            Long studentId=regRelativeVo.getStudentId();
                            Long relativePeriodId=regRelativeVo.getRelativePeriodId();
                            Integer chargingStatus=regRelativeVo.getChargingStatus();

                            ClassComletionDetailVo classComletionDetailVo=classComletionDetailVoMap.get(regId);

                            if (classComletionDetailVo==null){
                                classComletionDetailVo = new ClassComletionDetailVo();
                                BeanUtils.springCopyProperties(classComletionDetailVo, classComletionRateVo);

                                classComletionDetailVo.setStudentId(regRelativeVo.getStudentId());
                                classComletionDetailVo.setStudentName(regRelativeVo.getStudentName());
                                classComletionDetailVo.setStudentPhoneNo(regRelativeVo.getStudentPhoneNo());
                                classComletionDetailVoMap.put(regId,classComletionDetailVo);
                            }

                            if (!recordMap.containsKey(regId.toString()) && chargingStatus==2 ){
                                classComletionRateVo.setRegNum(classComletionRateVo.getRegNum()+1);
                                recordMap.put(regId.toString(),1);
                            }

                            if (relativeRegId!=null && StringUtils.isNotEmpty(regRelativeVo.getBonusClassIds())){
                                if (seqIdList!=null && seqIdList.contains(relativePeriodId) && regRelativeVo.getBonusClassIds().contains(regRelativeVo.getClassId().toString()) ){
                                    String key="seq"+"_"+studentId;
                                    if (!recordMap.containsKey(key)){
                                        classComletionRateVo.setSequentialPersonNum(classComletionRateVo.getSequentialPersonNum()+1);
                                        classComletionDetailVo.setSequentialDetail((StringUtils.isEmpty(classComletionDetailVo.getSequentialDetail())?"":classComletionDetailVo.getSequentialDetail()+",")+regRelativeVo.getRelativeCampusName()+ "/" + regRelativeVo.getRelativeGradeName()+ "/" + regRelativeVo.getRelativeClassName());
                                        List<RegRelativeVo> regRelativeVos=classComletionDetailVo.getSeqList();
                                        if (regRelativeVos==null){
                                            regRelativeVos=new ArrayList<>();
                                        }
                                        regRelativeVos.add(regRelativeVo);
                                        classComletionDetailVo.setSeqList(regRelativeVos);
                                        recordMap.put(key,1);
                                    }
                                }
                                if (stepIdList!=null && stepIdList.contains(relativePeriodId) && regRelativeVo.getBonusClassIds().contains(regRelativeVo.getClassId().toString())){
                                    String key="step"+"_"+studentId;
                                    if (!recordMap.containsKey(key)){
                                        classComletionRateVo.setStepPersonNum(classComletionRateVo.getStepPersonNum()+1);
                                        classComletionDetailVo.setStepDetail((StringUtils.isEmpty(classComletionDetailVo.getStepDetail())?"":classComletionDetailVo.getStepDetail()+",")+regRelativeVo.getRelativeCampusName()+ "/" + regRelativeVo.getRelativeGradeName()+ "/" + regRelativeVo.getRelativeClassName());
                                        List<RegRelativeVo> regRelativeVos=classComletionDetailVo.getStepList();
                                        if (regRelativeVos==null){
                                            regRelativeVos=new ArrayList<>();
                                        }
                                        regRelativeVos.add(regRelativeVo);
                                        classComletionDetailVo.setStepList(regRelativeVos);
                                        recordMap.put(key,1);
                                    }
                                }
                            }
                        }
                    }
                    Collection<ClassComletionDetailVo> classComletionDetailVos=classComletionDetailVoMap.values();
                    List<ClassComletionDetailVo> classComletionDetailVoList=new ArrayList<>(classComletionDetailVos);
                    classComletionRateVo.setClassComletionDetailVoList(classComletionDetailVoList);
                    classComletionRateVoList.add(classComletionRateVo);
                }
            }
            classComletionRateVoPage.setRecords(classComletionRateVoList);
        }
        return classComletionRateVoPage;

    }


    @Override
    public SXSSFWorkbook exportClassComletionRate(List<Long> periodIds,List<Long> busTeamIds,List<Long> gradeIds, CourseClassQueryVo courseClassQueryVo, DataPermission dataPermission,RegRelativceQueryVo regRelativceQueryVo,List<Integer> relativeTypes ){

        Page<ClassComletionRateVo> classComletionRateVoPage=this.findClassComletionRateVoPage(periodIds,busTeamIds,gradeIds,courseClassQueryVo,dataPermission,1,50000,regRelativceQueryVo);

        classComletionRateVoPage.setRecords(this.fillCanSeqStepRegNum(classComletionRateVoPage.getRecords(),periodIds));
        List<Long> teacherIds = Utils.removeDuplicate(BeanUtils.toList(classComletionRateVoPage.getRecords(), "teacherId"));
        List<Teacher> teacherList=teacherService.findByIds(teacherIds);
        Map<Long,Teacher> teacherMap=BeanUtils.toMap(teacherList,"teacherId");
        SXSSFWorkbook classComletionRate2excel = classComletionRate2excel(classComletionRateVoPage.getRecords(),teacherMap,sysUserRoleService.showIdNoByCheckRoleNames(Principals.get().id));

        return classComletionRate2excel;
    }
    private List<ClassComletionRateVo> fillCanSeqStepRegNum(List<ClassComletionRateVo> classComletionRateVos,List<Long> periodIds){
        if (Utils.checkListEmpty(classComletionRateVos)){
            return classComletionRateVos;
        }
        Map<String,String> seqMap=this.findRelativeSeqPeriodKeyNames();
        Map<String,String> stepMap=this.findRelativeStepPeriodKeyNames();

        List<PeriodRelativeVo> periodRelativeVoList=periodService.findPeriodRelativeByPeriodIds(periodIds);
        List<Long> relativePeriodIds=new ArrayList<>();
        for (PeriodRelativeVo periodRelativeVo :periodRelativeVoList){
            relativePeriodIds.addAll(periodRelativeVo.getRelativePeriodIds());
        }

        CourseClassQueryVo courseClassQueryVo=new CourseClassQueryVo();
        courseClassQueryVo.setStatusList(Arrays.asList(1,3));
        courseClassQueryVo.setPeriodIds(relativePeriodIds);

        List<CourseClass> courseClassList=courseClassService.findCourseClassListWithOutPermission(courseClassQueryVo,"classId","campusId","periodId","periodName","subjectId","gradeId");
        /*campusId+"_"+[寒春暑秋]+"_"+subjectId+"_"+gradeId*/
        Map<String,List<CourseClass>> map=new HashMap<>();
        if (courseClassList!=null){
            for (CourseClass courseClass:courseClassList){
                if (courseClass.getCampusId()==null){
                    continue;
                }
                String periodKey=this.findPeriodKeyName(courseClass.getPeriodName());
                String key=courseClass.getCampusId()+"_"+periodKey+"_"+courseClass.getSubjectId()+"_"+courseClass.getGradeId();
                List<CourseClass> courseClasses=map.get(key);
                if (courseClasses==null){
                    courseClasses=new ArrayList<>();
                    map.put(key,courseClasses);
                }
                courseClasses.add(courseClass);
            }
        }
        for (ClassComletionRateVo classComletionRateVo : classComletionRateVos) {
            classComletionRateVo.setCanSeqRegNum(classComletionRateVo.getRegNum());
            classComletionRateVo.setCanStepRegNum(classComletionRateVo.getRegNum());
            String periodKey = this.findPeriodKeyName(classComletionRateVo.getPeriodName());
            String seqMessage = seqMap.get(periodKey);
            if (StringUtils.isNotEmpty(seqMessage)) {
                String[] seqMessageArray = seqMessage.split("_");
                String seqKey = classComletionRateVo.getCampusId() + "_" + seqMessageArray[0] + "_" + classComletionRateVo.getSubjectId() + "_" + this.getRelativeGradeIdByKey(seqMessageArray[1],classComletionRateVo.getGradeId());
                List<CourseClass> haveCourseClassList = map.get(seqKey);
                if (Utils.checkListEmpty(haveCourseClassList)) {
                    classComletionRateVo.setCanSeqRegNum(0);
                }
            }
            String stepMessage = stepMap.get(periodKey);
            if (StringUtils.isNotEmpty(stepMessage)) {
                String[] stepMessageArray = stepMessage.split("_");
                String stepKey = classComletionRateVo.getCampusId() + "_" + stepMessageArray[0] + "_" + classComletionRateVo.getSubjectId() + "_" + this.getRelativeGradeIdByKey(stepMessageArray[1],classComletionRateVo.getGradeId());
                List<CourseClass> haveCourseClassList = map.get(stepKey);
                if (Utils.checkListEmpty(haveCourseClassList)) {
                    classComletionRateVo.setCanStepRegNum(0);
                }
            }
        }
        return classComletionRateVos;
    }


    private Long getRelativeGradeIdByKey(String key,Long gradeId){
        if ("0".equals(key)){
            return gradeId;
        }else if ("1".equals(key)){
            if (33L==gradeId || 99L==gradeId){
                return null;
            }else if (23L==gradeId){
                return 31L;
            }else if (16L==gradeId){
                return 21L;
            }else {
                return gradeId+1L;
            }
        }
        return null;
    }

    private  String findPeriodKeyName(String periodName){
        if (StringUtils.isNotEmpty(periodName)){
            if (periodName.contains("寒")){
                return "寒";
            }else if (periodName.contains("春")){
                return "春";
            }else if (periodName.contains("暑")){
                return "暑";
            }else if (periodName.contains("秋")){
                return "秋";
            }
        }
        return "";
    }

    private Map<String,String> findRelativeSeqPeriodKeyNames(){
        Map<String,String> map=new HashMap<>();
        map.put("寒","春_0");
        map.put("春","暑_1");
        map.put("暑","秋_0");
        map.put("秋","寒_0");
        return map;
    }
    private Map<String,String> findRelativeStepPeriodKeyNames(){
        Map<String,String> map=new HashMap<>();
        map.put("春","秋_1");
        map.put("秋","春_0");
        return map;
    }



    public static SXSSFWorkbook classLectureDetail2excel(SXSSFWorkbook excel ,List<ClassLectureDetail> classLectureDetailList,List<ClassLectureGroupDetailVo> classLectureGroupDetailVoList,Boolean showIdNo) {
        Map<Long,ClassLectureGroupDetailVo> classLectureGroupDetailVoMap=BeanUtils.toMap(classLectureGroupDetailVoList,"classId");
        SXSSFSheet sheet = excel.createSheet("老师任教情况详情");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"日期", "期数", "班级编号","班级", "校区","段次", "科目", "年级", "产品线", "教师", "任教性质", "班级总讲次", "任教讲次", "第几讲","主讲老师","身份证"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;

        TreeMap<String,OneDayClassLectureDetailVo> treeMap=new TreeMap<>();
        for (ClassLectureDetail classLectureDetail:classLectureDetailList){
            String key=Utils.formatDate(classLectureDetail.getClassDate(),"yyyy-MM-dd")+"_"+classLectureDetail.getTeacherId()+"_"+classLectureDetail.getClassId();
            OneDayClassLectureDetailVo oneDayClassLectureDetailVo=treeMap.get(key);
            if (oneDayClassLectureDetailVo==null){
                oneDayClassLectureDetailVo=new OneDayClassLectureDetailVo();
                BeanUtils.copyProperties(oneDayClassLectureDetailVo,classLectureDetail);
                oneDayClassLectureDetailVo.setTotalLectureNum(1);
                oneDayClassLectureDetailVo.setLectureNums(classLectureDetail.getLectureNo()+"");
            }else {
                oneDayClassLectureDetailVo.setTotalLectureNum(oneDayClassLectureDetailVo.getTotalLectureNum()+1);
                oneDayClassLectureDetailVo.setLectureNums(oneDayClassLectureDetailVo.getLectureNums()+","+classLectureDetail.getLectureNo()+"");
            }
            treeMap.put(key,oneDayClassLectureDetailVo);
        }
        for (Map.Entry<String,OneDayClassLectureDetailVo> entry:treeMap.entrySet()){
            OneDayClassLectureDetailVo classLectureDetail = entry.getValue();
            ClassLectureGroupDetailVo classLectureGroupDetailVo=null;
            if (classLectureDetail.getClassId()!=null){
                classLectureGroupDetailVo=classLectureGroupDetailVoMap.get(classLectureDetail.getClassId());
            }
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureDetail.getClassDate() == null ? StringUtils.EMPTY : Utils.formatDate(classLectureDetail.getClassDate(),"yyyy-MM-dd"));

            cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureDetail.getPeriodName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureGroupDetailVo==null?"":classLectureGroupDetailVo.getClassNo());

            cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureDetail.getClassName());


            cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureDetail.getCampusName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureDetail.getSegmentNo()==null?"":classLectureDetail.getSegmentNo().toString());

            cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureDetail.getSubjectName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureDetail.getGradeName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureDetail.getProductName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureDetail.getTeacherName());

         /*   cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureGroupDetailVo==null?"":classLectureGroupDetailVo.getIdNo());*/


            cell = row.createCell(cellNum++);
            cell.setCellValue(EnumUtils.getName(JobNatureEnum.values() ,classLectureDetail.getJobNature()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.formatString(classLectureDetail.getLectureAmount()));



            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(classLectureDetail.getTotalLectureNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureDetail.getLectureNums());

            cell = row.createCell(cellNum++);
            cell.setCellValue(classLectureGroupDetailVo==null?"":classLectureGroupDetailVo.getMainTeacherName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(showIdNo?(classLectureGroupDetailVo==null?"":classLectureGroupDetailVo.getIdNo()):"");

        }




        return excel;
    }


    public static SXSSFWorkbook classComletionRate2excel(List<ClassComletionRateVo> classComletionRateVoList,Map<Long,Teacher> teacherMap,Boolean showIdNo) {
        SXSSFWorkbook excel = new SXSSFWorkbook();

        excel=classComletionRateRepeat2excel(excel,classComletionRateVoList,teacherMap,showIdNo);
        return excel;
    }

    public static SXSSFWorkbook classComletionRateRepeat2excel(SXSSFWorkbook excel,List<ClassComletionRateVo> classComletionRateVoList,Map<Long,Teacher> teacherMap,Boolean showIdNo) {
        SXSSFSheet sheet = excel.createSheet("班级续读率去重表");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"区域", "业务组", "期数", "班级名称", "开课日期","结课日期","校区","段次", "学科", "年级", "教师","身份证","任教性质", "报名人数", "顺期可续人数","跨期可续人数","顺期人数", "顺期续读率", "目标顺期续读率", "跨期人数", "跨期续读率", "目标跨期续读率"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }

        SXSSFSheet detailSheet = excel.createSheet("班级续读率去重详情");
        SXSSFRow detailSheetRow = detailSheet.createRow(0);
        titles = new String[]{"期数", "段次", "业务组", "班级年级", "教师", "任教性质", "班级科目", "班名","学生姓名","学生电话号码", "顺期续读情况", "跨期续读情况"};
        for (int i = 0; i < titles.length; i++) {
            detailSheetRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;
        int detailRowNum = 1;
        for (int i = 0; i < classComletionRateVoList.size(); i++) {
            ClassComletionRateVo classComletionRateVo = classComletionRateVoList.get(i);
            Teacher teacher=teacherMap.get(classComletionRateVo.getTeacherId())==null?new Teacher():teacherMap.get(classComletionRateVo.getTeacherId());
            int cellNum = 0;

            SXSSFRow row = sheet.createRow(rowNum);
            rowNum++;
            SXSSFCell cell = row.createCell(cellNum);
            cell.setCellValue(classComletionRateVo.getAreaTeamName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(classComletionRateVo.getBusTeamName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(classComletionRateVo.getPeriodName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(classComletionRateVo.getClassName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(classComletionRateVo.getStartCourseTime() == null ? StringUtils.EMPTY : Utils.formatDate(classComletionRateVo.getStartCourseTime() , "yyyy-MM-dd"));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(classComletionRateVo.getEndCourseTime() == null ? StringUtils.EMPTY : Utils.formatDate(classComletionRateVo.getEndCourseTime() , "yyyy-MM-dd"));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(StringUtils.defaultString(classComletionRateVo.getCampusName()));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(classComletionRateVo.getSegmentNo()==null?"":classComletionRateVo.getSegmentNo().toString());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(classComletionRateVo.getSubjectName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(classComletionRateVo.getGradeName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(classComletionRateVo.getTeacherName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(StringUtils.defaultString(showIdNo?teacher.getIdNo():""));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(EnumUtils.getName(JobNatureEnum.values() ,classComletionRateVo.getJobNature()));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(classComletionRateVo.getRegNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(classComletionRateVo.getCanSeqRegNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(classComletionRateVo.getCanStepRegNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(classComletionRateVo.getSequentialPersonNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.getPercent(Utils.formatString(classComletionRateVo.getSequentialPersonNum()), Utils.formatString(classComletionRateVo.getRegNum()), 2));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.formatPercentString(classComletionRateVo.getSequentialTargetRate()));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(classComletionRateVo.getStepPersonNum())));
            cellNum++;


            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.getPercent(Utils.formatString(classComletionRateVo.getStepPersonNum()), Utils.formatString(classComletionRateVo.getRegNum()), 2));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.formatPercentString(classComletionRateVo.getStepTargetRate()));
            cellNum++;

            for (ClassComletionDetailVo classComletionDetailVo : classComletionRateVo.getClassComletionDetailVoList()) {
                int detailCellNum = 0;
                SXSSFRow detailRow = detailSheet.createRow(detailRowNum++);

                SXSSFCell detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(classComletionDetailVo.getPeriodName());

                detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(Utils.formatString(classComletionDetailVo.getSegmentNo()));

                detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(classComletionDetailVo.getBusTeamName());

                detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(classComletionDetailVo.getGradeName());

                detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(classComletionDetailVo.getTeacherName());


                detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(EnumUtils.getName(JobNatureEnum.values() ,classComletionDetailVo.getJobNature()));

              /*  detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(classComletionDetailVo.getTeacherName());*/

                detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(classComletionDetailVo.getSubjectName());

                detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(classComletionDetailVo.getClassName());

                detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(classComletionDetailVo.getStudentName());

                detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(classComletionDetailVo.getStudentPhoneNo());


                detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(StringUtils.defaultString(classComletionDetailVo.getSequentialDetail()));

                detailCell = detailRow.createCell(detailCellNum++);
                detailCell.setCellValue(StringUtils.defaultString(classComletionDetailVo.getStepDetail()));
            }
        }
        return excel;
    }


    @Override
    public Page<ClassLectureGroupDetailVo> findClassLectureGroupDetail(DataPermission dataPermission,List<Long> busTeamIds,List<Long> periodIds,List<Long> gradeIds,ClassLectureDetailQueryVo classLectureDetailQueryVo ,int pageNo,int pageSize) {
        if (classLectureDetailQueryVo.getAreaTeamId() == null) {
            throw new BusException("区域必选");
        }
        if (classLectureDetailQueryVo.getEndClassDate()!=null){
            classLectureDetailQueryVo.setEndClassDate(TimeUtils.changeOneDateLastTime(classLectureDetailQueryVo.getEndClassDate()));
        }

        if (pageNo==0){
            pageNo=1;
        }
        List<Long> subjectIds=classLectureDetailQueryVo.getSubjectId()!=null?Arrays.asList(classLectureDetailQueryVo.getSubjectId()):Utils.isEmpty(classLectureDetailQueryVo.getSubjectIds())?new ArrayList<>():classLectureDetailQueryVo.getSubjectIds();
        PerimissionTypeListVo perimissionTypeListVo=this.checkAndFillDataPerssion(dataPermission,classLectureDetailQueryVo.getAreaTeamId(),busTeamIds,gradeIds,subjectIds);
        busTeamIds=perimissionTypeListVo.getBusTeamIds();
        gradeIds=perimissionTypeListVo.getGradeIds();
        subjectIds=perimissionTypeListVo.getSubjectIds();
        classLectureDetailQueryVo.setSubjectId(null);
        classLectureDetailQueryVo.setSubjectIds(subjectIds);

        List<ClassLectureGroupDetailVo> classLectureGroupDetailVoList=classLectureDetailService.findClassLectureGroupDetail(periodIds,busTeamIds,gradeIds,classLectureDetailQueryVo,(pageNo-1)*pageSize,pageSize);
        List<Long> teacherIds=BeanUtils.toList(classLectureGroupDetailVoList,"teacherId");
        teacherIds=Utils.removeDuplicate(teacherIds);
        List<Teacher> teacherList=teacherService.findByIds(teacherIds);
        Map<Long,Teacher> teacherMap=BeanUtils.toMap(teacherList,"teacherId");

        List<Long> classIds=BeanUtils.toList(classLectureGroupDetailVoList,"classId");
        classIds=Utils.removeDuplicate(classIds);
        List<CourseClass> courseClassList=courseClassService.findByIds(classIds,"classId","teacherId","teacherName","lectureAmount","classNo");
        Map<Long,CourseClass> courseClassMap=BeanUtils.toMap(courseClassList,"classId");
        for (ClassLectureGroupDetailVo classLectureGroupDetailVo:classLectureGroupDetailVoList){
            Teacher teacher=teacherMap.get(classLectureGroupDetailVo.getTeacherId());
            if(teacher!=null){
                classLectureGroupDetailVo.setTeacherName(teacher.getTeacherName());
                classLectureGroupDetailVo.setIdNo(teacher.getIdNo());
            }
            CourseClass courseClass=courseClassMap.get(classLectureGroupDetailVo.getClassId());
            if (courseClass!=null){
                classLectureGroupDetailVo.setMainTeacherId(courseClass.getTeacherId());
                classLectureGroupDetailVo.setMainTeacherName(courseClass.getTeacherName());
                classLectureGroupDetailVo.setLectureAmount(courseClass.getLectureAmount());
                classLectureGroupDetailVo.setClassNo(courseClass.getClassNo());
            }
        }
        Integer total=classLectureDetailService.countClassLectureGroupDetail(periodIds,busTeamIds,gradeIds,classLectureDetailQueryVo);
        Page<ClassLectureGroupDetailVo> page=new Page<>(pageNo,pageSize);
        if(total==null){
            page.setTotal(0);
        }else {
            page.setTotal(total);
        }
        page.setRecords(classLectureGroupDetailVoList);
        return page;
    }

    @Override
    public SXSSFWorkbook exportClassLectureGroupDetail(DataPermission dataPermission,List<Long> busTeamIds,List<Long> periodIds,List<Long> gradeIds,ClassLectureDetailQueryVo classLectureDetailQueryVo) {
        List<ClassLectureDetail> classLectureDetailList=classLectureDetailService.findByQueryVo(periodIds,busTeamIds,gradeIds,classLectureDetailQueryVo);
        Page<ClassLectureGroupDetailVo> classLectureGroupDetailVoPage=this.findClassLectureGroupDetail(dataPermission,busTeamIds,periodIds,gradeIds,classLectureDetailQueryVo,1,50000);
        Boolean showIdNo=sysUserRoleService.showIdNoByCheckRoleNames(Principals.get().id);
        SXSSFWorkbook excel =classLectureGroup2excel(classLectureGroupDetailVoPage.getRecords(),showIdNo);
        excel=classLectureDetail2excel(excel,classLectureDetailList,classLectureGroupDetailVoPage.getRecords(),showIdNo);
        return excel;
    }

    public static SXSSFWorkbook classLectureGroup2excel(List<ClassLectureGroupDetailVo> classLectureGroupDetailVoList,Boolean showIdNo) {
        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("教师任教情况");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"期数","班级编号", "班级名称", "校区","段次", "学科", "年级", "教师","任教性质", "班级总讲次", "任教讲次", "第几讲","主讲老师","身份证"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }

        int rowNum = 1;

        if (classLectureGroupDetailVoList != null) {
            for (ClassLectureGroupDetailVo classLectureGroupDetailVo:classLectureGroupDetailVoList) {
                int cellNum = 0;
                SXSSFRow row = sheet.createRow(rowNum++);
                SXSSFCell cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classLectureGroupDetailVo.getPeriodName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classLectureGroupDetailVo.getClassNo()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classLectureGroupDetailVo.getClassName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classLectureGroupDetailVo.getCampusName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(classLectureGroupDetailVo.getSegmentNo()==null?"":classLectureGroupDetailVo.getSegmentNo().toString());

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classLectureGroupDetailVo.getSubjectName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classLectureGroupDetailVo.getGradeName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classLectureGroupDetailVo.getTeacherName()));

          /*      cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classLectureGroupDetailVo.getIdNo()));
*/
                cell = row.createCell(cellNum++);
                cell.setCellValue(EnumUtils.getName(JobNatureEnum.values() ,classLectureGroupDetailVo.getJobNature()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(classLectureGroupDetailVo.getLectureAmount()==null?0:classLectureGroupDetailVo.getLectureAmount());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classLectureGroupDetailVo.getTotalLectureNum()==null?0:classLectureGroupDetailVo.getTotalLectureNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classLectureGroupDetailVo.getLectureNums()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classLectureGroupDetailVo.getMainTeacherName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(showIdNo?classLectureGroupDetailVo.getIdNo():""));
            }
        }
        return excel;
    }


    @Override
    public List<GradeCompletionRateVo> findGradeCompletionVoList(Long areaTeamId, List<Long> busTeamIds, List<Long> periodIds, List<Long> gradeIds,List<Long> subjectIds) {
        PeriodSeqStepSituationVo periodSeqStepSituationVo=periodService.findPeriodSeqStepSituation(periodIds);
        List<Period> periodList = periodSeqStepSituationVo.getPeriodList();
        Map<Long,List<Long>> seqMap=periodSeqStepSituationVo.getSeqMap();
        Map<Long,List<Long>> stepMap=periodSeqStepSituationVo.getStepMap();
        List<Long> seqStepList=periodSeqStepSituationVo.getSeqStepList();
        List<Long> allPeriodIds = periodSeqStepSituationVo.getAllPeriodIds();
        Map<Long,Map<Integer,PeriodSegment>> periodSegmentMap=periodSeqStepSituationVo.getPeriodSegmentMap();



        PeriodQueryRegVo periodQueryRegVo=new PeriodQueryRegVo();
        periodQueryRegVo.setAreaTeamId(areaTeamId);
        periodQueryRegVo.setBusTeamIds(busTeamIds);
        periodQueryRegVo.setPeriodIds(periodIds);
        periodQueryRegVo.setGradeIds(gradeIds);
        periodQueryRegVo.setSubjectIds(subjectIds);

        periodQueryRegVo.setChargingStatus(2);
        periodQueryRegVo.setRegStatus(0);
        RegRelativceQueryVo regRelativceQueryVo=new RegRelativceQueryVo();
        regRelativceQueryVo.setNeedSameSubject(1);

        regRelativceQueryVo.setPeriodIds(seqStepList);

        List<RegRelativeVo> regRelativeVoList=mergeStudentRegDetailService.queryRegRelative(periodQueryRegVo,regRelativceQueryVo);
        regRelativeVoList=mergeStudentRegDetailService.filterListByEffectiveLectureNum(regRelativeVoList,periodSegmentMap);
        regRelativeVoList=mergeStudentRegDetailService.filterListByReportConfig(allPeriodIds,regRelativeVoList,ReportResourceEnum.校区续读.id);
        Map<Long, List<RegRelativeVo>> regRelativeVoMap = BeanUtils.toGroup(regRelativeVoList, "busTeamId");

        List<MainAccountTarget> mainAccountTargetList = mainAccountTargetService.findByGroupId(busTeamIds, gradeIds, periodIds);

        Map<Long, List<MainAccountTarget>> mainAccountTargetMap = BeanUtils.toGroup(mainAccountTargetList, "mainAccountId");

        List<GradeCompletionRateVo> gradeCompletionRateVoList = new ArrayList<GradeCompletionRateVo>();
        //   List<RegRelativce> regRelativceList=regRelativceService.findByBusTeamIdPeriodIdGradeId(regRelativceQueryVo,busTeamIds,periodIds,gradeIds,relativeTypes,"busTeamId","periodId","gradeId","recordChargingStatus","relativeType");
        List<BaseGrade> baseGradeList=null;
        if(Utils.checkListEmpty(gradeIds)){
            baseGradeList=baseGradeService.findAllOrderGrade();
        }else {
            baseGradeList=baseGradeService.findDealOtherPosition(gradeIds);
        }
        List<BusTeam> busTeamList = busTeamService.findListOrderByAreaTeamId(busTeamIds);

        for (BusTeam busTeam : busTeamList) {
            Long busTeamId=busTeam.getBusTeamId();
            List<RegRelativeVo> busTeamRegRelativeList= regRelativeVoMap.get(busTeamId);
            Map<Long, List<RegRelativeVo>> busTeamRegRelativeMap = BeanUtils.toGroup(busTeamRegRelativeList, "periodId");

            List<MainAccountTarget> mainAccountTargetBusTeamList = mainAccountTargetMap.get(busTeamId);
            Map<Long, List<MainAccountTarget>> mainAccountTargetBusTeamMap = BeanUtils.toGroup(mainAccountTargetBusTeamList, "periodId");

            for (Period period : periodList) {
                Long periodId=period.getPeriodId();
                List<Long> seqIdList=seqMap.get(periodId);
                List<Long> stepIdList=stepMap.get(periodId);
                List<RegRelativeVo> busTeamPeriodRegRelativeList=busTeamRegRelativeMap.get(periodId);
                Map<Long, List<RegRelativeVo>> busTeamPeriodRegRelativeMap = BeanUtils.toGroup(busTeamPeriodRegRelativeList, "gradeId");


                List<MainAccountTarget> mainAccountTargetBusTeamPeriodList = mainAccountTargetBusTeamMap.get(periodId);
                Map<Long, List<MainAccountTarget>> mainAccountTargetBusTeamPeriodMap = BeanUtils.toGroup(mainAccountTargetBusTeamPeriodList, "groupId");

                for (BaseGrade baseGrade : baseGradeList) {
                    Map<String,Integer> recordMap=new HashMap<>();
                    Long gradeId=baseGrade.getGradeId();
                    List<RegRelativeVo> busTeamPeriodGradeRegRelativeList=busTeamPeriodRegRelativeMap.get(gradeId);

                    GradeCompletionRateVo gradeCompletionRateVo=new GradeCompletionRateVo();
                    gradeCompletionRateVo.setBusTeamId(busTeam.getBusTeamId());
                    gradeCompletionRateVo.setBusTeamName(busTeam.getName());
                    gradeCompletionRateVo.setAreaTeamId(busTeam.getAreaTeamId());
                    gradeCompletionRateVo.setAreaTeamName(busTeam.getAreaTeamName());
                    gradeCompletionRateVo.setPeriodId(period.getPeriodId());
                    gradeCompletionRateVo.setPeriodName(period.getPeriodName());
                    gradeCompletionRateVo.setGradeName(baseGrade.getGradeName());
                    gradeCompletionRateVo.setGradeId(baseGrade.getGradeId());
                    if (busTeamPeriodGradeRegRelativeList!=null){
                        for (RegRelativeVo regRelativeVo:busTeamPeriodGradeRegRelativeList){

                            Long studentId=regRelativeVo.getStudentId();
                            Integer studentState=regRelativeVo.getStudentState();
                            Integer chargingStatus=regRelativeVo.getChargingStatus();

                            if (studentState==null){
                                continue;
                            }
                            Long regId=regRelativeVo.getRegId();
                            if (!recordMap.containsKey(regId.toString()) && chargingStatus==2 ){
                                gradeCompletionRateVo.setNowPeriodNum(gradeCompletionRateVo.getNowPeriodNum()+1);
                                if (studentState==0){
                                    gradeCompletionRateVo.setRealNewStudentNum(gradeCompletionRateVo.getRealNewStudentNum()+1);
                                }else if (studentState==1){
                                    gradeCompletionRateVo.setRealOldStudentNum(gradeCompletionRateVo.getRealOldStudentNum()+1);
                                }
                                recordMap.put(regId.toString(),1);
                            }
                            if (!recordMap.containsKey(studentId.toString()) && chargingStatus==2){
                                if (studentState==0){
                                    gradeCompletionRateVo.setNewPersonNum(gradeCompletionRateVo.getNewPersonNum()+1);
                                }else if (studentState==1){
                                    gradeCompletionRateVo.setOldPersonNum(gradeCompletionRateVo.getOldPersonNum()+1);
                                }
                                gradeCompletionRateVo.setNowPersonNum(gradeCompletionRateVo.getNowPersonNum()+1);
                                recordMap.put(studentId.toString(),1);
                            }
                            Long relativeRegId=regRelativeVo.getRelativeRegId();
                            Long relativePeriodId=regRelativeVo.getRelativePeriodId();

                            if (relativeRegId!=null){
                                if (seqIdList!=null && seqIdList.contains(relativePeriodId)){
                                    String key="seq"+"_"+studentId;
                                    gradeCompletionRateVo.setSequentialNum(gradeCompletionRateVo.getSequentialNum()+1);
                                    if (!recordMap.containsKey(key)){
                                        gradeCompletionRateVo.setSeqPersonNum(gradeCompletionRateVo.getSeqPersonNum()+1);
                                        recordMap.put(key,1);
                                    }
                                }
                                if (stepIdList!=null && stepIdList.contains(relativePeriodId)){
                                    String key="step"+"_"+studentId;
                                    gradeCompletionRateVo.setStepNum(gradeCompletionRateVo.getStepNum()+1);
                                    if (!recordMap.containsKey(key)){
                                        gradeCompletionRateVo.setStepPersonNum(gradeCompletionRateVo.getStepPersonNum()+1);
                                        recordMap.put(key,1);
                                    }
                                }
                            }
                        }
                    }

                    List<MainAccountTarget> mainAccountTargetBusTeamPeriodGradeList = mainAccountTargetBusTeamPeriodMap.get(gradeId);
                    if (mainAccountTargetBusTeamPeriodGradeList!=null){
                        for (MainAccountTarget mainAccountTarget : mainAccountTargetBusTeamPeriodGradeList) {
                            String fullTargetType = mainAccountTarget.getTargetType();
                            String targetType = fullTargetType.substring(fullTargetType.length()-2,fullTargetType.length());
                            String numStr = mainAccountTarget.getTargetNum();
                            if (StringUtils.isEmpty(numStr)) {
                                continue;
                            }

                            if (TargetTypeEnum.NEW_STUDENT_NUM.id.equals(targetType)) {
                                gradeCompletionRateVo.setTargetNewStudentNum(numStr.trim());
                            } else if (TargetTypeEnum.OLD_STUDENT_NUM.id.equals(targetType)) {
                                gradeCompletionRateVo.setTargetOldSudentNum(numStr.trim());
                            } else if (TargetTypeEnum.SEQUENTIA_NUM.id.equals(targetType)) {
                                gradeCompletionRateVo.setTargetSequentialNum(numStr.trim());
                            } else if (TargetTypeEnum.STEP_NUM.id.equals(targetType)) {
                                gradeCompletionRateVo.setTargetStepNum(numStr.trim());
                            } else if (TargetTypeEnum.NEW_OLD_STUDENT_NUM.id.equals(targetType)){
                                gradeCompletionRateVo.setTargetNewOldStudentNum(numStr.trim());
                            }
                        }
                    }
                    gradeCompletionRateVo.setRealNewOldStudentNum(gradeCompletionRateVo.getRealNewStudentNum()+gradeCompletionRateVo.getRealOldStudentNum());
                    gradeCompletionRateVoList.add(gradeCompletionRateVo);
                }
            }
        }
        return gradeCompletionRateVoList;
    }



    @Override
    @Cacheable(value = "CacheOfBusTeamPeriodSeqStepNum",key = "#areaTeamId+'_'+#busTeamId+'_'+#periodId")
    public BusTeamPeriodSeqStepNumVo findBusTeamPeriodSeqStepNum(long areaTeamId, long busTeamId, long periodId) {

        BusTeamPeriodSeqStepNumVo busTeamPeriodSeqStepNumVo=new BusTeamPeriodSeqStepNumVo();
        busTeamPeriodSeqStepNumVo.setBusTeamId(busTeamId);
        busTeamPeriodSeqStepNumVo.setPeriodId(periodId);
        List<GradeCompletionRateVo> gradeCompletionVoList = this.findGradeCompletionVoList(areaTeamId, Arrays.asList(busTeamId), Arrays.asList(periodId), null, null);
        if (Utils.checkListNotEmpty(gradeCompletionVoList)){
            for (GradeCompletionRateVo gradeCompletionRateVo:gradeCompletionVoList){
                busTeamPeriodSeqStepNumVo.setNowPeriodNum(busTeamPeriodSeqStepNumVo.getNowPeriodNum()+gradeCompletionRateVo.getNowPeriodNum());
                busTeamPeriodSeqStepNumVo.setSequentialNum(busTeamPeriodSeqStepNumVo.getSequentialNum()+gradeCompletionRateVo.getSequentialNum());
                busTeamPeriodSeqStepNumVo.setStepNum(busTeamPeriodSeqStepNumVo.getStepNum()+gradeCompletionRateVo.getStepNum());
            }
        }
        return busTeamPeriodSeqStepNumVo;

    }

    @Override
    public SXSSFWorkbook exportGradeCompletionRate(Long areaTeamId, List<Long> busTeamIds, List<Long> periodIds, List<Long> gradeIds) {
        if (busTeamIds == null || busTeamIds.size() <= 0 || gradeIds == null || gradeIds.size() <= 0) {
            throw new BusException("缺乏必填参数");
        }
        List<GradeCompletionRateVo> gradeCompletionRateVoList = this.findGradeCompletionVoList(areaTeamId,busTeamIds,periodIds,gradeIds,null);

        SXSSFWorkbook mainAccountGradeCompletionRate = gradeCompletionRate2excel(gradeCompletionRateVoList);

        return mainAccountGradeCompletionRate;
    }




    @Override
    public Page<SeniorCompletionRateVo> findSeniorComletionRateVoPage(TeacherQueryVo teacherQueryVo, List<Long> busTeamIds, List<Long> periodIds, List<Long> gradeIds, int pageNo, int pageSize) {
        List<SeniorCompletionRateVo> seniorCompletionRateVoList = new ArrayList<>();
        Page<Teacher> teacherPage = teacherService.findTeacherByBusTeamListForPage(teacherQueryVo, busTeamIds, pageNo, pageSize);
        Page<SeniorCompletionRateVo> seniorCompletionRateVoPage = Utils.newPage(teacherPage);
        List<Teacher> teacherList = teacherPage.getRecords();


        PeriodSeqStepSituationVo periodSeqStepSituationVo=periodService.findPeriodSeqStepSituation(periodIds);
        List<Period> periodList = periodSeqStepSituationVo.getPeriodList();
        Map<Long,List<Long>> seqMap=periodSeqStepSituationVo.getSeqMap();
        Map<Long,List<Long>> stepMap=periodSeqStepSituationVo.getStepMap();
        List<Long> seqStepList=periodSeqStepSituationVo.getSeqStepList();
        Map<Long,Map<Integer,PeriodSegment>> periodSegmentMap=periodSeqStepSituationVo.getPeriodSegmentMap();
        List<Long> allPeriodIds = periodSeqStepSituationVo.getAllPeriodIds();


        if (teacherList != null && teacherList.size() > 0) {
            List<Long> teacherIdList = BeanUtils.toList(teacherList, "teacherId");
            PeriodQueryRegVo periodQueryRegVo = new PeriodQueryRegVo();
            periodQueryRegVo.setSeniorIds(teacherIdList);
            periodQueryRegVo.setPeriodIds(periodIds);
            //periodQueryRegVo.setLectureNum(5);
            periodQueryRegVo.setGradeIds(gradeIds);
            periodQueryRegVo.setRegStatus(0);
            periodQueryRegVo.setChargingStatus(2);
            RegRelativceQueryVo regRelativceQueryVo = new RegRelativceQueryVo();
            regRelativceQueryVo.setPeriodIds(seqStepList);
            //regRelativceQueryVo.setBigRecordLectureNum(5);
            regRelativceQueryVo.setNeedSameSubject(1);


            List<RegRelativeVo> regRelativeVoList = mergeStudentRegDetailService.queryRegRelative(periodQueryRegVo, regRelativceQueryVo);
            regRelativeVoList=mergeStudentRegDetailService.filterListByEffectiveLectureNum(regRelativeVoList,periodSegmentMap);
            regRelativeVoList=mergeStudentRegDetailService.filterListByReportConfig(allPeriodIds,regRelativeVoList,ReportResourceEnum.营运班主任续读.id);

            /*春季高三不算续读*/
            regRelativeVoList = regRelativeVoList.stream().filter(item -> !(item.getPeriodName().contains("春季") && item.getGradeId().equals(33L))).collect(Collectors.toList());


            List<Long> studentIdList = BeanUtils.toList(regRelativeVoList, "studentId");
            studentIdList = Utils.removeDuplicate(studentIdList);
            PeriodQueryRegVo queryRegVo = new PeriodQueryRegVo();
            queryRegVo.setChargingStatus(2);
            //queryRegVo.setLectureNum(5);
            queryRegVo.setRegStatus(0);
            List<MergeStudentRegDetail> mergeStudentRegDetailList = null;
            if (teacherIdList.size() <= 200) {
                mergeStudentRegDetailList = mergeStudentRegDetailService.findByStudentIdsPeriodIds(studentIdList, seqStepList, queryRegVo);
            } else {
                mergeStudentRegDetailList = mergeStudentRegDetailService.findByAreaTeamIdPeriodIds(teacherQueryVo.getAreaTeamId(), seqStepList, queryRegVo);
            }

            mergeStudentRegDetailList=mergeStudentRegDetailService.filterRegByEffectiveLectureNum(mergeStudentRegDetailList,periodSegmentMap);
            mergeStudentRegDetailList=mergeStudentRegDetailService.filteRegByReportConfig(seqStepList,mergeStudentRegDetailList,ReportResourceEnum.营运班主任续读.id);
            //
            Map<Long, List<MergeStudentRegDetail>> studentRegMap = BeanUtils.toGroup(mergeStudentRegDetailList, "studentId");

            List<TeacherTarget> teacherTargets = teacherTargetService.findListByTeachersAndPeriodIds(teacherIdList, periodIds);
            Map<Long, List<TeacherTarget>> map = BeanUtils.toGroup(teacherTargets, "periodId");

            Map<Long, List<RegRelativeVo>> relativeMap = BeanUtils.toGroup(regRelativeVoList, "periodId");

            for (Period period : periodList) {
                Long periodId = period.getPeriodId();
                List<Long> seqIdList = seqMap.get(periodId);
                List<Long> stepIdList = stepMap.get(periodId);
                List<RegRelativeVo> studentRegDetailPeriod = relativeMap.get(period.getPeriodId());
                Map<Long, List<RegRelativeVo>> relativeTeacherMap = BeanUtils.toGroup(studentRegDetailPeriod, "seniorId");
                List<TeacherTarget> teacherTargetListPeriod = map.get(periodId);
                Map<Long, List<TeacherTarget>> teacherMap = BeanUtils.toGroup(teacherTargetListPeriod, "teacherId");
                for (Teacher teacher : teacherList) {
                    Map<String, Integer> recordMap = new HashMap<>();
                    Map<Long, SeniorRegDetailVo> seniorRegDetailVoMap = new HashMap<>();
                    SeniorCompletionRateVo seniorCompletionRateVo = new SeniorCompletionRateVo();
                    List<TeacherTarget> teacherTargetList = teacherMap.get(teacher.getTeacherId());
                    if (teacherTargetList != null) {
                        for (TeacherTarget teacherTarget : teacherTargetList) {
                            Integer targetTypeInt = teacherTarget.getTargetType();
                            String targetType =targetTypeInt+"";
                            String numStr = teacherTarget.getTargetNum();
                            //Integer num=Integer.parseInt(numStr);
                            if (StringUtils.isEmpty(numStr)) {
                                continue;
                            }
                            if (TargetTypeEnum.NEW_STUDENT_NUM.id.equals(targetType)) {
                                seniorCompletionRateVo.setTargetNewStudentNum(Integer.parseInt(numStr.trim()));
                            } else if (TargetTypeEnum.OLD_STUDENT_NUM.id.equals(targetType)) {
                                seniorCompletionRateVo.setTargetOldSudentNum(Integer.parseInt(numStr.trim()));
                            } else if (TargetTypeEnum.SEQUENTIA_NUM.id.equals(targetType)) {
                                seniorCompletionRateVo.setTargetSequentialNum(numStr.trim());
                            } else if (TargetTypeEnum.STEP_NUM.id.equals(targetType)) {
                                seniorCompletionRateVo.setTargetStepNum(numStr.trim());
                            }
                        }
                    }

                    seniorCompletionRateVo.setBusTeamId(teacher.getBusTeamId());
                    seniorCompletionRateVo.setBusTeamName(teacher.getBusTeamName());
                    seniorCompletionRateVo.setPeriodId(periodId);
                    seniorCompletionRateVo.setPeriodName(period.getPeriodName());
                    seniorCompletionRateVo.setTeacherName(teacher.getTeacherName());
                    seniorCompletionRateVo.setTeacherId(teacher.getTeacherId());

                    List<RegRelativeVo> oneSeniorRegList = relativeTeacherMap.get(teacher.getTeacherId());
                    if (oneSeniorRegList != null) {
                        for (RegRelativeVo regRelativeVo : oneSeniorRegList) {

                            Long regId = regRelativeVo.getRegId();
                            Long studentId = regRelativeVo.getStudentId();
                            Integer chargingStatus = regRelativeVo.getChargingStatus();

                            SeniorRegDetailVo seniorRegDetailVo = seniorRegDetailVoMap.get(studentId);
                            if (seniorRegDetailVo == null) {
                                seniorRegDetailVo = new SeniorRegDetailVo();
                                seniorRegDetailVo.setPeriodId(period.getPeriodId());
                                seniorRegDetailVo.setPeriodName(period.getPeriodName());
                                seniorRegDetailVo.setSeniorBusTeamId(teacher.getBusTeamId());
                                seniorRegDetailVo.setSeniorBusTeamName(teacher.getBusTeamName());
                                seniorRegDetailVo.setSeniorId(teacher.getTeacherId());
                                seniorRegDetailVo.setSeniorName(teacher.getTeacherName());
                                seniorRegDetailVo.setStudentId(regRelativeVo.getStudentId());
                                seniorRegDetailVo.setStudentName(regRelativeVo.getStudentName());
                                seniorRegDetailVo.setStudentPhoneNo(regRelativeVo.getStudentPhoneNo());
                                seniorRegDetailVoMap.put(studentId, seniorRegDetailVo);
                            }

                            if (!recordMap.containsKey(regId.toString())) {
                                seniorCompletionRateVo.setNowPeriodNum(seniorCompletionRateVo.getNowPeriodNum() + 1);
                                seniorRegDetailVo.setNowPeriodDetail((StringUtils.isEmpty(seniorRegDetailVo.getNowPeriodDetail()) ? "" : seniorRegDetailVo.getNowPeriodDetail() + ",") + regRelativeVo.getCampusName() + "/" + regRelativeVo.getGradeName() + "/" + regRelativeVo.getClassName());
                                recordMap.put(regId.toString(), 1);
                            }
                            if (!recordMap.containsKey(studentId.toString()) && chargingStatus == 2) {
                                seniorCompletionRateVo.setRealPersonNum(seniorCompletionRateVo.getRealPersonNum() + 1);
                                recordMap.put(studentId.toString(), 1);
                            }
                            Long relativeRegId = regRelativeVo.getRelativeRegId();
                            Long relativePeriodId = regRelativeVo.getRelativePeriodId();

                            if (relativeRegId != null) {
                                if (seqIdList != null && seqIdList.contains(relativePeriodId)) {
                                    String key = "seq" + "_" + studentId;
                                    seniorCompletionRateVo.setSequentialNum(seniorCompletionRateVo.getSequentialNum() + 1);
                                    seniorRegDetailVo.setSequentialDetail((StringUtils.isEmpty(seniorRegDetailVo.getSequentialDetail()) ? "" : seniorRegDetailVo.getSequentialDetail() + ",") + regRelativeVo.getRelativeCampusName() + "/" + regRelativeVo.getRelativeGradeName() + "/" + regRelativeVo.getRelativeClassName());
                                    List<Long> seqRegIds = seniorRegDetailVo.getSeqRegIds();
                                    if (seqRegIds == null) {
                                        seqRegIds = new ArrayList<>();
                                    }
                                    seqRegIds.add(regRelativeVo.getRelativeRegId());
                                    seniorRegDetailVo.setSeqRegIds(seqRegIds);
                                    if (!recordMap.containsKey(key)) {
                                        seniorCompletionRateVo.setSeqPersonNum(seniorCompletionRateVo.getSeqPersonNum() + 1);
                                        recordMap.put(key, 1);
                                    }
                                }
                                if (stepIdList != null && stepIdList.contains(relativePeriodId)) {
                                    String key = "step" + "_" + studentId;
                                    seniorCompletionRateVo.setStepNum(seniorCompletionRateVo.getStepNum() + 1);
                                    seniorRegDetailVo.setStepDetail((StringUtils.isEmpty(seniorRegDetailVo.getStepDetail()) ? "" : seniorRegDetailVo.getStepDetail() + ",") + regRelativeVo.getRelativeCampusName() + "/" + regRelativeVo.getRelativeGradeName() + "/" + regRelativeVo.getRelativeClassName());
                                    if (!recordMap.containsKey(key)) {
                                        seniorCompletionRateVo.setStepPersonNum(seniorCompletionRateVo.getStepPersonNum() + 1);
                                        recordMap.put(key, 1);
                                    }
                                    List<Long> stepRegIds = seniorRegDetailVo.getStepRegIds();
                                    if (stepRegIds == null) {
                                        stepRegIds = new ArrayList<>();
                                    }
                                    stepRegIds.add(regRelativeVo.getRelativeRegId());
                                    seniorRegDetailVo.setStepRegIds(stepRegIds);
                                }
                            }
                        }
                    }
                    seniorCompletionRateVo.setSequentialRate(Utils.getPercent(seniorCompletionRateVo.getSequentialNum().toString(), seniorCompletionRateVo.getNowPeriodNum().toString(), 2));
                    seniorCompletionRateVo.setStepRate(Utils.getPercent(seniorCompletionRateVo.getStepNum().toString(), seniorCompletionRateVo.getNowPeriodNum().toString(), 2));
                    Collection<SeniorRegDetailVo> seniorRegDetailVoCollection = seniorRegDetailVoMap.values();
                    List<SeniorRegDetailVo> seniorRegDetailVoList = new ArrayList<>(seniorRegDetailVoCollection);
                    for (SeniorRegDetailVo seniorRegDetailVo : seniorRegDetailVoList) {
                        Long studentId = seniorRegDetailVo.getStudentId();
                        List<MergeStudentRegDetail> mergeStudentRegDetails = studentRegMap.get(studentId);
                        if (mergeStudentRegDetails != null) {
                            for (MergeStudentRegDetail mergeStudentRegDetail : mergeStudentRegDetails) {

                                Long studentRegPeriodId = mergeStudentRegDetail.getPeriodId();
                                Long studentRegRegId = mergeStudentRegDetail.getRegId();
                                if (seqIdList.contains(studentRegPeriodId)) {
                                    if (seniorRegDetailVo.getSeqRegIds() == null || !seniorRegDetailVo.getSeqRegIds().contains(studentRegRegId)) {
                                        seniorRegDetailVo.setSeqDevelopDetail((StringUtils.isEmpty(seniorRegDetailVo.getSeqDevelopDetail()) ? "" : seniorRegDetailVo.getSeqDevelopDetail() + ",") + mergeStudentRegDetail.getCampusName() + "/" + mergeStudentRegDetail.getGradeName() + "/" + mergeStudentRegDetail.getClassName());
                                    }
                                }
                                if (stepIdList.contains(studentRegPeriodId)) {
                                    if (seniorRegDetailVo.getStepRegIds() == null || !seniorRegDetailVo.getStepRegIds().contains(studentRegRegId)) {
                                        seniorRegDetailVo.setStepDevelopDetail((StringUtils.isEmpty(seniorRegDetailVo.getStepDevelopDetail()) ? "" : seniorRegDetailVo.getStepDevelopDetail() + ",") + mergeStudentRegDetail.getCampusName() + "/" + mergeStudentRegDetail.getGradeName() + "/" + mergeStudentRegDetail.getClassName());
                                    }
                                }
                            }
                        }
                    }


                    seniorCompletionRateVo.setSeniorRegDetailVoList(seniorRegDetailVoList);
                    seniorCompletionRateVoList.add(seniorCompletionRateVo);
                }
            }
        }
        seniorCompletionRateVoPage.setRecords(seniorCompletionRateVoList);
        return seniorCompletionRateVoPage;
    }

    @Override
    public List<StudentContinueRegDetailVo> findStudentContinueRegDetail(TeacherQueryVo teacherQueryVo,List<Long> busTeamIds, List<Long> periodIds, List<Long> gradeIds) {
        PeriodSeqStepSituationVo periodSeqStepSituationVo=periodService.findPeriodSeqStepSituation(periodIds);
        Map<Long,List<Long>> seqMap=periodSeqStepSituationVo.getSeqMap();
        Map<Long,List<Long>> stepMap=periodSeqStepSituationVo.getStepMap();
        List<Long> seqStepList=periodSeqStepSituationVo.getSeqStepList();
        List<Long> allPeriodIds = periodSeqStepSituationVo.getAllPeriodIds();
        Map<Long,Map<Integer,PeriodSegment>> periodSegmentMap=periodSeqStepSituationVo.getPeriodSegmentMap();



        Page<Teacher> teacherPage = teacherService.findTeacherByBusTeamListForPage(teacherQueryVo, busTeamIds, 1, 20000);
        if (teacherPage.getRecords()==null){
            return Collections.EMPTY_LIST;
        }
        List<Long> teacherIds=BeanUtils.toList(teacherPage.getRecords(),"teacherId");

        PeriodQueryRegVo periodQueryRegVo=new PeriodQueryRegVo();
        periodQueryRegVo.setPeriodIds(periodIds);
        //periodQueryRegVo.setLectureNum(5);
        periodQueryRegVo.setGradeIds(gradeIds);
        periodQueryRegVo.setRegStatus(0);
        periodQueryRegVo.setChargingStatus(2);
        periodQueryRegVo.setSeniorIds(teacherIds);
        RegRelativceQueryVo regRelativceQueryVo=new RegRelativceQueryVo();
        regRelativceQueryVo.setPeriodIds(seqStepList);
        //regRelativceQueryVo.setBigRecordLectureNum(5);
        regRelativceQueryVo.setNeedSameSubject(1);
        List<RegRelativeVo> regRelativeVoList=mergeStudentRegDetailService.queryRegRelative(periodQueryRegVo,regRelativceQueryVo);
        regRelativeVoList=mergeStudentRegDetailService.filterListByEffectiveLectureNum(regRelativeVoList,periodSegmentMap);
        regRelativeVoList=mergeStudentRegDetailService.filterListByReportConfig(allPeriodIds,regRelativeVoList,ReportResourceEnum.营运班主任续读.id);

        Map<Long,List<RegRelativeVo>> periodRegRelativeMap=BeanUtils.toGroup(regRelativeVoList,"periodId");


        PeriodQueryRegVo queryRegVo=new PeriodQueryRegVo();
        queryRegVo.setChargingStatus(2);
        //queryRegVo.setLectureNum(5);
        queryRegVo.setRegStatus(0);
        List<MergeStudentRegDetail> mergeStudentRegDetailList =mergeStudentRegDetailService.findByAreaTeamIdPeriodIds(teacherQueryVo.getAreaTeamId(),seqStepList,queryRegVo);
        mergeStudentRegDetailList=mergeStudentRegDetailService.filterRegByEffectiveLectureNum(mergeStudentRegDetailList,periodSegmentMap);
        mergeStudentRegDetailList=mergeStudentRegDetailService.filteRegByReportConfig(seqStepList,mergeStudentRegDetailList,ReportResourceEnum.营运班主任续读.id);
        Map<Long,List<MergeStudentRegDetail>> studentRegMap=BeanUtils.toGroup(mergeStudentRegDetailList,"studentId");
        List<StudentContinueRegDetailVo> studentContinueRegDetailVoList=new ArrayList<>();

        for (Long periodId:periodIds){
            Map<String,Integer> recordMap=new HashMap<>();
            List<RegRelativeVo> periodRegRelativeList=periodRegRelativeMap.get(periodId);
            List<Long> seqIdList = seqMap.get(periodId);
            List<Long> stepIdList = stepMap.get(periodId);

            if (periodRegRelativeList!=null){
                List<Long> studentIdList = BeanUtils.toList(periodRegRelativeList, "studentId");
                studentIdList=Utils.removeDuplicate(studentIdList);

                Map<Long,List<RegRelativeVo>> studentPeriodRegRelativeMap=BeanUtils.toGroup(periodRegRelativeList,"studentId");
                for (Long studentId:studentIdList){
                    List<RegRelativeVo> studentPeriodRegRelativeList=studentPeriodRegRelativeMap.get(studentId);
                    if (studentContinueRegDetailVoList==null){
                        continue;
                    }
                    StudentContinueRegDetailVo studentContinueRegDetailVo = new StudentContinueRegDetailVo();

                    Set<String> seniorNameSet=new HashSet<>();
                    for (RegRelativeVo regRelativeVo : studentPeriodRegRelativeList) {

                        studentContinueRegDetailVo.setStudentId(studentId);
                        studentContinueRegDetailVo.setPeriodId(periodId);
                        Long regId = regRelativeVo.getRegId();
                        Long relativeRegId = regRelativeVo.getRelativeRegId();
                        Long relativePeriodId = regRelativeVo.getRelativePeriodId();

                        studentContinueRegDetailVo.setStudentName(regRelativeVo.getStudentName());
                        studentContinueRegDetailVo.setStudentPhoneNo(regRelativeVo.getStudentPhoneNo());
                        studentContinueRegDetailVo.setPeriodName(regRelativeVo.getPeriodName());
                        if (!recordMap.containsKey(regId.toString())) {
                            if (regRelativeVo.getSeniorId()!=null && StringUtils.isNotEmpty(regRelativeVo.getSeniorName()) ){
                                seniorNameSet.add(regRelativeVo.getSeniorName());
                            }
                            studentContinueRegDetailVo.setNowPeriodDetail((StringUtils.isEmpty(studentContinueRegDetailVo.getNowPeriodDetail()) ? "" : studentContinueRegDetailVo.getNowPeriodDetail() + ",") + regRelativeVo.getCampusName() + "/" + regRelativeVo.getGradeName() + "/" + regRelativeVo.getClassName());
                            recordMap.put(regId.toString(), 1);
                        }

                        if (relativeRegId != null) {
                            String key = "seq" + "_" + relativeRegId;
                            if (seqIdList != null && seqIdList.contains(relativePeriodId) &&!recordMap.containsKey(key)) {

                                studentContinueRegDetailVo.setSequentialDetail((StringUtils.isEmpty(studentContinueRegDetailVo.getSequentialDetail()) ? "" : studentContinueRegDetailVo.getSequentialDetail() + ",") + regRelativeVo.getRelativeCampusName() + "/" + regRelativeVo.getRelativeGradeName() + "/" + regRelativeVo.getRelativeClassName());
                                List<Long> seqRegIds = studentContinueRegDetailVo.getSeqRegIds();
                                if (seqRegIds == null) {
                                    seqRegIds = new ArrayList<>();
                                }
                                seqRegIds.add(regRelativeVo.getRelativeRegId());
                                studentContinueRegDetailVo.setSeqRegIds(seqRegIds);
                                recordMap.put(key, 1);
                            }
                            key = "step" + "_" + relativeRegId;
                            if (stepIdList != null && stepIdList.contains(relativePeriodId) && !recordMap.containsKey(key)) {

                                studentContinueRegDetailVo.setStepDetail((StringUtils.isEmpty(studentContinueRegDetailVo.getStepDetail()) ? "" : studentContinueRegDetailVo.getStepDetail() + ",") + regRelativeVo.getRelativeCampusName() + "/" + regRelativeVo.getRelativeGradeName() + "/" + regRelativeVo.getRelativeClassName());
                                recordMap.put(key, 1);

                                List<Long> stepRegIds = studentContinueRegDetailVo.getStepRegIds();
                                if (stepRegIds == null) {
                                    stepRegIds = new ArrayList<>();
                                }
                                stepRegIds.add(regRelativeVo.getRelativeRegId());
                                studentContinueRegDetailVo.setStepRegIds(stepRegIds);
                            }
                        }


                    }
                    List<MergeStudentRegDetail> oneMergeStudentRegDetailList =studentRegMap.get(studentId);
                    if (oneMergeStudentRegDetailList !=null){
                        for (MergeStudentRegDetail mergeStudentRegDetail : oneMergeStudentRegDetailList){

                            Long studentRegPeriodId = mergeStudentRegDetail.getPeriodId();
                            Long studentRegRegId = mergeStudentRegDetail.getRegId();
                            String key="seqDevelop" + "_" + studentRegRegId;
                            if (!recordMap.containsKey(key) && seqIdList.contains(studentRegPeriodId)) {
                                if (studentContinueRegDetailVo.getSeqRegIds() == null || !studentContinueRegDetailVo.getSeqRegIds().contains(studentRegRegId)) {
                                    studentContinueRegDetailVo.setSeqDevelopDetail((StringUtils.isEmpty(studentContinueRegDetailVo.getSeqDevelopDetail()) ? "" : studentContinueRegDetailVo.getSeqDevelopDetail() + ",") + mergeStudentRegDetail.getCampusName() + "/" + mergeStudentRegDetail.getGradeName() + "/" + mergeStudentRegDetail.getClassName());
                                    recordMap.put(key, 1);
                                }
                            }
                            key="stepDevelop" + "_" + studentRegRegId;
                            if (!recordMap.containsKey(key) && stepIdList.contains(studentRegPeriodId)) {
                                if (studentContinueRegDetailVo.getStepRegIds() == null || !studentContinueRegDetailVo.getStepRegIds().contains(studentRegRegId)) {
                                    studentContinueRegDetailVo.setStepDevelopDetail((StringUtils.isEmpty(studentContinueRegDetailVo.getStepDevelopDetail()) ? "" : studentContinueRegDetailVo.getStepDevelopDetail() + ",") + mergeStudentRegDetail.getCampusName() + "/" + mergeStudentRegDetail.getGradeName() + "/" + mergeStudentRegDetail.getClassName());
                                    recordMap.put(key, 1);
                                }
                            }
                        }
                    }
                    studentContinueRegDetailVo.setSeniorNames(StringUtils.join(seniorNameSet,","));
                    if (studentContinueRegDetailVo.getStudentId()!=null){
                        studentContinueRegDetailVoList.add(studentContinueRegDetailVo);
                    }
                }


            }

        }

        return  studentContinueRegDetailVoList;
    }

    @Override
    public SXSSFWorkbook exportSeniorComletionRate(TeacherQueryVo teacherQueryVo,List<Long> busTeamIds,List<Long> periodIds,List<Long> gradeIds) {
        Page<SeniorCompletionRateVo> seniorCompletionRateVoPage=this.findSeniorComletionRateVoPage(teacherQueryVo,busTeamIds,periodIds,gradeIds,1,10000);
        List<SeniorCompletionRateVo> seniorCompletionRateVos=seniorCompletionRateVoPage.getRecords();

        SXSSFWorkbook excel = seniorComletionRate2excel(seniorCompletionRateVos);

        List<StudentContinueRegDetailVo> studentContinueRegDetailVoList=this.findStudentContinueRegDetail(teacherQueryVo,busTeamIds,periodIds,gradeIds);
        studentOnlyStepContinueRegDetail2excel(excel,seniorCompletionRateVos);
        studentContinueRegDetail2excel(excel,studentContinueRegDetailVoList);
        return excel;
    }

    @Override
    public Page<CounselorRateVo> findCounselorComletionRateVoPage(PeriodQueryRegVo periodQueryRegVo, TeacherQueryVo teacherQueryVo, List<Long> busTeamIds, List<Long> periodIds, int pageNo, int pageSize) {
        Page<Teacher> teacherPage = teacherService.findTeacherByBusTeamListForPage(teacherQueryVo,busTeamIds,pageNo,pageSize);
        Page<CounselorRateVo> counselorRateVoPage = Utils.newPage(teacherPage);
        List<Teacher> teacherList = teacherPage.getRecords();
        List<Period> periodList=periodService.findByIds(periodIds);
        List<PeriodSegment> periodSegmentList=periodSegmentService.findByPeriodSegmentListByPeriodIds(periodIds);
        Map<Long,Map<Integer,PeriodSegment>> periodSegmentMap=periodSegmentService.periodSegmentToMapGroup(periodSegmentList);
        if (teacherList != null && teacherList.size() > 0) {
            List<Long> teacherIdList = BeanUtils.toList(teacherList, "teacherId");
            List<MergeStudentRegDetail> mergeStudentRegDetailList =mergeStudentRegDetailService.findByCounselorIdsPeriodIdsStates(teacherIdList,periodIds,Arrays.asList(0,1),periodQueryRegVo,studentRegDetailColumns);
            mergeStudentRegDetailList=mergeStudentRegDetailService.filterRegByEffectiveLectureNum(mergeStudentRegDetailList,periodSegmentMap);
            mergeStudentRegDetailList=mergeStudentRegDetailService.filteRegByReportConfig(periodIds,mergeStudentRegDetailList,ReportResourceEnum.营运咨询师科数.id);
            List<TeacherTarget> teacherTargets = teacherTargetService.findListByTeacherIdsAndPeriodIds(teacherIdList,periodIds,null,Arrays.asList(10));
            List<CounselorRateVo> counselorRateVoList=this.toCounselorComletionRateList(teacherList,periodList,teacherTargets, mergeStudentRegDetailList);
            counselorRateVoPage.setRecords(counselorRateVoList);
        }
        return counselorRateVoPage;
    }


    @Override
    public SXSSFWorkbook exportCounselorComletionRateVoPage(PeriodQueryRegVo periodQueryRegVo, TeacherQueryVo teacherQueryVo, List<Long> busTeamIds, List<Long> periodIds) {
        Page<CounselorRateVo> page=this.findCounselorComletionRateVoPage(periodQueryRegVo,teacherQueryVo,busTeamIds,periodIds,1,20000);
        return counselorComletionRate2excel(page.getRecords());
    }
    public static SXSSFWorkbook counselorComletionRate2excel(List<CounselorRateVo> counselorRateVos) {
        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("咨询师科数（营运指标）");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{ "业务组", "期数", "咨询师","实际新生科数", "实际老生科数", "实际新老生科数", "目标新老生科数","新老生科数完成率"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;


        SXSSFSheet sheet1 = excel.createSheet("咨询师科数详情");
        SXSSFRow firstRow1 = sheet1.createRow(0);
        String[] titles1 = new String[]{"业务组", "期数", "咨询师","学生姓名", "学生电话号码", "生源类型", "学号","年级","科数"};
        int rowNum1 = 1;
        for (int i = 0; i < titles1.length; i++) {
            firstRow1.createCell(i).setCellValue(titles1[i]);
        }

        if (counselorRateVos!=null){
            for (CounselorRateVo counselorRateVo : counselorRateVos) {
                int cellNum = 0;

                SXSSFRow row = sheet.createRow(rowNum++);



                SXSSFCell  cell = row.createCell(cellNum++);
                cell.setCellValue(counselorRateVo.getBusTeamName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(counselorRateVo.getPeriodName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(counselorRateVo.getTeacherName());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(counselorRateVo.getRealNewStudentNum());



                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(counselorRateVo.getRealOldStudentNum());


                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(counselorRateVo.getRealNewOldStudentNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(counselorRateVo.getTargetNewOldStudentNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(counselorRateVo.getNewOldStudentRate()));

                for (CounselorOperaRegDetail counselorOperaRegDetail:counselorRateVo.getCounselorOperaRegDetailList()){
                    int cellNum1 = 0;
                    SXSSFRow row1 = sheet1.createRow(rowNum1);
                    rowNum1++;
                    SXSSFCell cell1 = row1.createCell(cellNum1++);
                    cell1.setCellValue(StringUtils.defaultString(counselorOperaRegDetail.getBusTeamName()));

                    cell1 = row1.createCell(cellNum1++);
                    cell1.setCellValue(StringUtils.defaultString(counselorOperaRegDetail.getPeriodName()));

                    cell1 = row1.createCell(cellNum1++);
                    cell1.setCellValue(StringUtils.defaultString(counselorOperaRegDetail.getCounselorName()));

                    cell1 = row1.createCell(cellNum1++);
                    cell1.setCellValue(StringUtils.defaultString(counselorOperaRegDetail.getStudentName()));


                    cell1 = row1.createCell(cellNum1++);
                    cell1.setCellValue(StringUtils.defaultString(counselorOperaRegDetail.getStudentPhoneNo()));

                    cell1 = row1.createCell(cellNum1++);
                    cell1.setCellValue(counselorOperaRegDetail.getStudentState()==null?"":counselorOperaRegDetail.getStudentState()==0?"新生":"老生");

                    cell1 = row1.createCell(cellNum1++);
                    cell1.setCellValue(StringUtils.defaultString(counselorOperaRegDetail.getStudentNo()));

                    cell1 = row1.createCell(cellNum1++);
                    cell1.setCellValue(StringUtils.defaultString(counselorOperaRegDetail.getStudentGradeName()));

                    cell1 = row1.createCell(cellNum1++);
                    cell1.setCellType(CellType.NUMERIC);
                    cell1.setCellValue(counselorOperaRegDetail.getRegNum());
                }


            }
        }


        return excel;
    }





    private  List<CounselorRateVo> toCounselorComletionRateList(List<Teacher> teacherList, List<Period> periodList, List<TeacherTarget> teacherTargetList, List<MergeStudentRegDetail> mergeStudentRegDetailList){
        Map<Long, List<MergeStudentRegDetail>> periodRegDetailMap = BeanUtils.toGroup(mergeStudentRegDetailList, "periodId");
        Map<Long,List<TeacherTarget>>  periodTargetMap=BeanUtils.toGroup(teacherTargetList,"periodId");
        List<CounselorRateVo> counselorRateVos=new ArrayList<>();
        for (Period period:periodList){
            List<TeacherTarget> periodTeacherTargets=periodTargetMap.get(period.getPeriodId());
            List<MergeStudentRegDetail> periodRegDetail=periodRegDetailMap.get(period.getPeriodId());
            for (Teacher teacher:teacherList){
                Map<Long,List<TeacherTarget>> onePeriodTeacherTargetMap=BeanUtils.toGroup(periodTeacherTargets,"teacherId");
                Map<Long,List<MergeStudentRegDetail>> onePeriodSeniorRegDetailMap=BeanUtils.toGroup(periodRegDetail,"counselorId");
                List<TeacherTarget> onePeriodTeacherTarget=onePeriodTeacherTargetMap.get(teacher.getTeacherId());
                List<MergeStudentRegDetail> onePeriodSeniorRegDetail=onePeriodSeniorRegDetailMap.get(teacher.getTeacherId());
                counselorRateVos.add(this.toCounselorRate(teacher,period,onePeriodTeacherTarget,onePeriodSeniorRegDetail));
            }
        }
        return  counselorRateVos;
    }
    private CounselorRateVo toCounselorRate(Teacher teacher,Period period,List<TeacherTarget> onePeriodTeacherTarget,List<MergeStudentRegDetail> onePeriodSeniorRegDetail){
        CounselorRateVo counselorRateVo=new CounselorRateVo();
        BeanUtils.copyProperties(counselorRateVo,teacher);
        counselorRateVo.setPeriodId(period.getPeriodId());
        counselorRateVo.setPeriodName(period.getPeriodName());
        if (onePeriodSeniorRegDetail!=null){
            Iterator<MergeStudentRegDetail> mergeStudentRegDetailIterator=onePeriodSeniorRegDetail.iterator();
            while (mergeStudentRegDetailIterator.hasNext()){
                MergeStudentRegDetail mergeStudentRegDetail=mergeStudentRegDetailIterator.next();
                counselorRateVo.setRealNewOldStudentNum(counselorRateVo.getRealNewOldStudentNum()+1);
                if (mergeStudentRegDetail.getStudentState()==0){
                    counselorRateVo.setRealNewStudentNum(counselorRateVo.getRealNewStudentNum()+1);
                }else if(mergeStudentRegDetail.getStudentState()==1){
                    counselorRateVo.setRealOldStudentNum(counselorRateVo.getRealOldStudentNum()+1);
                }
            }
        }
        if (onePeriodTeacherTarget!=null){
            for (TeacherTarget teacherTarget : onePeriodTeacherTarget) {
                //  Integer targetType = teacherTarget.getTargetType();
                String numStr = teacherTarget.getTargetNum();
                if (StringUtils.isEmpty(numStr)) {
                    continue;
                }
                counselorRateVo.setTargetNewOldStudentNum(Integer.parseInt(numStr.trim()));

            }
        }
        //counselorRateVo.setNewStudentRate(Utils.getPercent(counselorRateVo.getRealNewStudentNum().toString(),counselorRateVo.getTargetNewStudentNum().toString(),2));
        //counselorRateVo.setOldStudentRate(Utils.getPercent(counselorRateVo.getRealOldStudentNum().toString(),counselorRateVo.getTargetOldStudentNum().toString(),2));
        counselorRateVo.setNewOldStudentRate(Utils.getPercent(counselorRateVo.getRealNewOldStudentNum().toString(),counselorRateVo.getTargetNewOldStudentNum().toString(),2));
        counselorRateVo.setCounselorOperaRegDetailList(this.toCounselorRegDetailList(onePeriodSeniorRegDetail));
        return counselorRateVo;
    }
    private  List<CounselorOperaRegDetail> toCounselorRegDetailList(List<MergeStudentRegDetail> mergeStudentRegDetailList){
        Map<Long,List<MergeStudentRegDetail>> studentMap=BeanUtils.toGroup(mergeStudentRegDetailList,"studentId");
        List<CounselorOperaRegDetail> counselorOperaRegDetails=new ArrayList<>(studentMap.size());
        for(Map.Entry<Long,List<MergeStudentRegDetail>> entry:studentMap.entrySet()){
            List<MergeStudentRegDetail> oneStudentRegList=entry.getValue();
            Map<Long,List<MergeStudentRegDetail>> map=BeanUtils.toGroup(oneStudentRegList,"campusId");
            for (Map.Entry<Long,List<MergeStudentRegDetail>> campusEntry:map.entrySet()){
                CounselorOperaRegDetail counselorOperaRegDetail=new CounselorOperaRegDetail();
                List<MergeStudentRegDetail> oneCampusStudentRegList=campusEntry.getValue();
                for (MergeStudentRegDetail mergeStudentRegDetail :oneCampusStudentRegList){
                    if (counselorOperaRegDetail.getStudentId()==null){
                        BeanUtils.copyProperties(counselorOperaRegDetail, mergeStudentRegDetail);
                    }
                    counselorOperaRegDetail.setRegNum(counselorOperaRegDetail.getRegNum()+1);

                }
                counselorOperaRegDetails.add(counselorOperaRegDetail);
            }

        }
        return counselorOperaRegDetails;
    }

    @Override
    public SitutaionVo findBusinessSituationList(DataPermission dataPermission,Long areaTeamId,List<Long> busTeamIds, List<Long> periodIds, List<Long> gradeIds,List<Long> subjectIds, Date startDate, Date endDate,int needWithPeriod,int findPeriodGradeSubject ) {
        Principals.Principal principal=Principals.get();
        if (endDate == null) {
            throw new BusException("请选择报读结束日期");
        }
        if (endDate!=null){
            endDate=TimeUtils.changeOneDateLastTime(endDate);
            //regRelativceQueryVo.setEndRecordRegTime(TimeUtils.changeOneDateLastTime(regRelativceQueryVo.getEndRecordRegTime()));
        }

        PerimissionTypeListVo perimissionTypeListVo = this.checkAndFillDataPerssion(dataPermission, areaTeamId, busTeamIds, gradeIds, subjectIds);
        busTeamIds=perimissionTypeListVo.getBusTeamIds();
        gradeIds=perimissionTypeListVo.getGradeIds();
        subjectIds=perimissionTypeListVo.getSubjectIds();

        SitutaionVo situtaionVo=new SitutaionVo();
        endDate = TimeUtils.changeOneDateLastTime(endDate);
        AreaTeam areaTeam=areaTeamService.findById(areaTeamId);

        List<BusTeam> busTeamList=busTeamService.findByIds(busTeamIds);
        Map<Long, BusTeam> busTeamMap = BeanUtils.toMap(busTeamList, "busTeamId");

        PeriodRegVo periodRegVo = this.findPeriodAndWithPeriod(areaTeamId, busTeamIds, periodIds, gradeIds, subjectIds, startDate, endDate, Arrays.asList(0, 3), needWithPeriod, 1);


        List<BaseGrade> baseGradeList = baseGradeService.findDealOtherPosition(gradeIds);
        Map<Long, BaseGrade> gradeMap = BeanUtils.toMap(baseGradeList, "gradeId");

        List<BaseSubject> baseSubjectList = baseSubjectService.findAllFromCache();
        Map<Long, BaseSubject> subjectMap = BeanUtils.toMap(baseSubjectList, "subjectId");

        List<Period> allPeriod = periodRegVo.getPeriodList();
        Map<Long, Period> periodMap = BeanUtils.toMap(allPeriod, "periodId");

        List<Long> allPeriodIds = BeanUtils.toList(allPeriod, "periodId");


        List<MergeStudentRegDetail> mergeStudentRegDetailList = periodRegVo.getMergeStudentRegDetailList();
        Map<String, PeriodGradeSubjectSituationVo> periodGradeSubjectSituationVoMap = new HashMap<>();
        Map<String, List<Long>> periodGradeSubjectStudentRecord = new HashMap<>();

        Map<String, BusinessSituationVo> businessSituationVoMap = new TreeMap<>();
        Map<String, List<Long>> periodBusTeamGradeStudentRecord = new TreeMap<>();

        if (mergeStudentRegDetailList != null) {
            for (MergeStudentRegDetail mergeStudentRegDetail : mergeStudentRegDetailList) {
                BusTeam busTeam=busTeamMap.get(mergeStudentRegDetail.getBusTeamId());
                BaseGrade baseGrade=gradeMap.get(mergeStudentRegDetail.getGradeId());
                Period period=periodMap.get(mergeStudentRegDetail.getPeriodId());
                BaseSubject baseSubject=subjectMap.get(mergeStudentRegDetail.getSubjectId());
                if (mergeStudentRegDetail.getStudentState() == null) {
                    continue;
                }
                if (findPeriodGradeSubject==1){
                    this.fillPeriodGradeSubjectSituationMapByReg(areaTeam,period,baseGrade,baseSubject,periodGradeSubjectSituationVoMap, periodGradeSubjectStudentRecord, mergeStudentRegDetail);
                }

                this.fillBusinessSituationMapByReg(busTeam,baseGrade,period,businessSituationVoMap, periodBusTeamGradeStudentRecord, mergeStudentRegDetail);
            }
        }
        List<StudentRefund> studentRefundList = periodRegVo.getStudentRefundList();
        Map<String, List<StudentRefund>> refundRegMap = new HashMap<>();
        if (studentRefundList != null) {
            for (StudentRefund studentRefund : studentRefundList) {
                String key = studentRefund.getStudentId() + "_" + studentRefund.getClassId();
                List<StudentRefund> studentRefunds = refundRegMap.get(key);
                if (studentRefunds == null) {
                    studentRefunds = new ArrayList<>();
                    refundRegMap.put(key, studentRefunds);
                }
                studentRefunds.add(studentRefund);

            }
        }

        List<MergeStudentRegDetail> refundRegList = periodRegVo.getRefundRegDetails();
        if (refundRegList != null) {
            for (MergeStudentRegDetail mergeStudentRegDetail : refundRegList) {
                BusTeam busTeam=busTeamMap.get(mergeStudentRegDetail.getBusTeamId());
                BaseGrade baseGrade=gradeMap.get(mergeStudentRegDetail.getGradeId());
                Period period=periodMap.get(mergeStudentRegDetail.getPeriodId());
                BaseSubject baseSubject=subjectMap.get(mergeStudentRegDetail.getSubjectId());
                if (findPeriodGradeSubject==1){
                    this.fillPeriodGradeSubjectSituationMapByRegRefund(areaTeam,period,baseGrade,baseSubject,periodGradeSubjectSituationVoMap, periodGradeSubjectStudentRecord, mergeStudentRegDetail, refundRegMap);
                }

                this.fillBusinessSituationMapByRegRefund(busTeam,baseGrade,period,businessSituationVoMap, periodBusTeamGradeStudentRecord, mergeStudentRegDetail, refundRegMap);
            }
        }

        List<String> businessGradeClassIncomeTypeList=new ArrayList<>();
        for (BaseGrade baseGrade:baseGradeList){
            businessGradeClassIncomeTypeList.add(baseGrade.getGradeId().toString()+"55");
        }

        List<MainAccountTarget> mainAccountTargetList = mainAccountTargetService.findListByMainAccountIdsAndPeriodIdsAndTargetTypes(busTeamIds, allPeriodIds,businessGradeClassIncomeTypeList);

        for (MainAccountTarget mainAccountTarget:mainAccountTargetList){
            BaseGrade baseGrade=gradeMap.get(mainAccountTarget.getGroupId());
            Period period=periodMap.get(mainAccountTarget.getPeriodId());
            BusTeam busTeam=busTeamMap.get(mainAccountTarget.getMainAccountId());
            this.fillBusinessSituationMapByTarget(businessSituationVoMap,mainAccountTarget,period,busTeam,baseGrade);
        }

        if (findPeriodGradeSubject==1){
            List<String> periodGradeSubjectClassInomeTypeList=new ArrayList<>();
            for (BaseGrade baseGrade:baseGradeList){
                if (findPeriodGradeSubject==1){
                    for (BaseSubject baseSubject:baseSubjectList){
                        periodGradeSubjectClassInomeTypeList.add(baseGrade.getGradeId().toString()+"-"+baseSubject.getSubjectId().toString()+"-"+"99");
                    }
                }
            }
            List<MainAccountTarget> periodGradeSubjectTargetList = mainAccountTargetService.findListByMainAccountIdsAndPeriodIdsAndTargetTypes(Arrays.asList(areaTeamId), allPeriodIds,periodGradeSubjectClassInomeTypeList);
            for (MainAccountTarget mainAccountTarget:periodGradeSubjectTargetList){
                BaseGrade baseGrade=gradeMap.get(mainAccountTarget.getGroupId());
                Period period=periodMap.get(mainAccountTarget.getPeriodId());
                BaseSubject baseSubject=subjectMap.get(Long.parseLong(mainAccountTarget.getTargetType().split("-")[1]));
                this.fillPeriodGradeSubjectSituationMapByTarget(areaTeam,periodGradeSubjectSituationVoMap,mainAccountTarget,period,baseGrade,baseSubject);
            }
        }
        Collection<BusinessSituationVo> businessSituationVoCollection = businessSituationVoMap.values();
        situtaionVo.setBusinessSituationVoList(new ArrayList<>(businessSituationVoCollection));

        Collection<PeriodGradeSubjectSituationVo> periodGradeSubjectSituationVoCollection = periodGradeSubjectSituationVoMap.values();
        situtaionVo.setPeriodGradeSubjectSituationVoList(new ArrayList<>(periodGradeSubjectSituationVoCollection));
        return situtaionVo;
    }

    private void fillPeriodGradeSubjectSituationMapByReg(AreaTeam areaTeam,Period period,BaseGrade baseGrade,BaseSubject baseSubject,Map<String, PeriodGradeSubjectSituationVo> periodGradeSubjectSituationVoMap, Map<String, List<Long>> periodGradeSubjectStudentRecord, MergeStudentRegDetail mergeStudentRegDetail) {
        String periodGradeSubjectSituationkey = mergeStudentRegDetail.getPeriodId() + "_" + mergeStudentRegDetail.getGradeId() + "_" + mergeStudentRegDetail.getSubjectId();
        String periodGradeSubjectStudentKey = periodGradeSubjectSituationkey + "_" + mergeStudentRegDetail.getStudentId()+"_"+mergeStudentRegDetail.getStudentState();
        PeriodGradeSubjectSituationVo periodGradeSubjectSituationVo = periodGradeSubjectSituationVoMap.get(periodGradeSubjectSituationkey);
        if (periodGradeSubjectSituationVo == null) {
            periodGradeSubjectSituationVo = new PeriodGradeSubjectSituationVo();
            periodGradeSubjectSituationVo.setAreaTeamName(areaTeam.getName());
            periodGradeSubjectSituationVo.setAreaTeamId(areaTeam.getAreaTeamId());
            periodGradeSubjectSituationVo.setPeriodId(period.getPeriodId());
            periodGradeSubjectSituationVo.setPeriodName(period.getPeriodName());
            periodGradeSubjectSituationVo.setGradeId(baseGrade.getGradeId());
            periodGradeSubjectSituationVo.setGradeName(baseGrade.getGradeName());
            periodGradeSubjectSituationVo.setSubjectId(baseSubject.getSubjectId());
            periodGradeSubjectSituationVo.setSubjectName(baseSubject.getSubjectName());
            periodGradeSubjectSituationVoMap.put(periodGradeSubjectSituationkey, periodGradeSubjectSituationVo);
        }
        BigDecimal realAmount = mergeStudentRegDetail.getPayAmount();
        periodGradeSubjectSituationVo.setTotalAmount(periodGradeSubjectSituationVo.getTotalAmount().add(mergeStudentRegDetail.getSrcTotalAmount()));
        periodGradeSubjectSituationVo.setRealAmount(periodGradeSubjectSituationVo.getRealAmount().add(realAmount));
        if (mergeStudentRegDetail.getRegStatus() == 0) {
            periodGradeSubjectSituationVo.setDiscountAmount(periodGradeSubjectSituationVo.getDiscountAmount().add(mergeStudentRegDetail.getSrcTotalAmount().subtract(mergeStudentRegDetail.getTotalAmount())));

        }
        switch (mergeStudentRegDetail.getStudentState()) {
            case 0:
                periodGradeSubjectSituationVo.setNewStudentAmount(periodGradeSubjectSituationVo.getNewStudentAmount().add(realAmount));
                periodGradeSubjectSituationVo.setNewStudentNum(periodGradeSubjectSituationVo.getNewStudentNum() + 1);
                if (!periodGradeSubjectStudentRecord.containsKey(periodGradeSubjectStudentKey)) {
                    periodGradeSubjectSituationVo.setNewStudentPersonNum(periodGradeSubjectSituationVo.getNewStudentPersonNum() + 1);
                }
                break;
            case 1:
                periodGradeSubjectSituationVo.setOldStudentAmount(periodGradeSubjectSituationVo.getOldStudentAmount().add(realAmount));
                if (!periodGradeSubjectStudentRecord.containsKey(periodGradeSubjectStudentKey)) {
                    periodGradeSubjectSituationVo.setOldStudentPersonNum(periodGradeSubjectSituationVo.getOldStudentPersonNum() + 1);
                }
                periodGradeSubjectSituationVo.setOldStudentNum(periodGradeSubjectSituationVo.getOldStudentNum() + 1);
                break;
            case 2:
                periodGradeSubjectSituationVo.setSeqStepAmount(periodGradeSubjectSituationVo.getSeqStepAmount().add(realAmount));
                if (!periodGradeSubjectStudentRecord.containsKey(periodGradeSubjectStudentKey)) {
                    periodGradeSubjectSituationVo.setSeqStepPersonNum(periodGradeSubjectSituationVo.getSeqStepPersonNum() + 1);
                }
                periodGradeSubjectSituationVo.setSeqStepNum(periodGradeSubjectSituationVo.getSeqStepNum() + 1);
                break;
            default:
                break;
        }
        List<Long> studentRegIdList = periodGradeSubjectStudentRecord.get(periodGradeSubjectStudentKey);
        if (studentRegIdList == null) {
            studentRegIdList = new ArrayList<>();
        }
        studentRegIdList.add(mergeStudentRegDetail.getRegId());
        periodGradeSubjectStudentRecord.put(periodGradeSubjectStudentKey, studentRegIdList);
    }

    private void fillPeriodGradeSubjectSituationMapByRegRefund(AreaTeam areaTeam,Period period,BaseGrade baseGrade,BaseSubject baseSubject,Map<String, PeriodGradeSubjectSituationVo> periodGradeSubjectSituationVoMap, Map<String, List<Long>> periodGradeSubjectStudentRecord, MergeStudentRegDetail mergeStudentRegDetail,Map<String,List<StudentRefund>> refundRegMap) {
        String periodGradeSubjectSituationkey = mergeStudentRegDetail.getPeriodId() + "_" + mergeStudentRegDetail.getGradeId() + "_" + mergeStudentRegDetail.getSubjectId();
        String periodGradeSubjectStudentKey = periodGradeSubjectSituationkey + "_" + mergeStudentRegDetail.getStudentId()+"_"+mergeStudentRegDetail.getStudentState();
        PeriodGradeSubjectSituationVo periodGradeSubjectSituationVo = periodGradeSubjectSituationVoMap.get(periodGradeSubjectSituationkey);
        if (periodGradeSubjectSituationVo == null) {
            periodGradeSubjectSituationVo = new PeriodGradeSubjectSituationVo();
            periodGradeSubjectSituationVo.setAreaTeamName(areaTeam.getName());
            periodGradeSubjectSituationVo.setAreaTeamId(areaTeam.getAreaTeamId());
            periodGradeSubjectSituationVo.setPeriodId(period.getPeriodId());
            periodGradeSubjectSituationVo.setPeriodName(period.getPeriodName());
            periodGradeSubjectSituationVo.setGradeId(baseGrade.getGradeId());
            periodGradeSubjectSituationVo.setGradeName(baseGrade.getGradeName());
            periodGradeSubjectSituationVo.setSubjectId(baseSubject.getSubjectId());
            periodGradeSubjectSituationVo.setSubjectName(baseSubject.getSubjectName());
            periodGradeSubjectSituationVoMap.put(periodGradeSubjectSituationkey, periodGradeSubjectSituationVo);
        }
        List<StudentRefund> oneStudentRefundList = refundRegMap.get(mergeStudentRegDetail.getStudentId() + "_" + mergeStudentRegDetail.getClassId());
        if (oneStudentRefundList == null) {
            return;
        }
        BigDecimal totalRefundAmount = BigDecimal.ZERO;
        for (StudentRefund studentRefund : oneStudentRefundList) {
            BigDecimal refundAmount = studentRefund.getAmount();
            totalRefundAmount = totalRefundAmount.add(refundAmount);
            Integer branchNum = 0;
            BigDecimal studentRegRefund = mergeStudentRegDetail.getRefundAmount() == null ? BigDecimal.ZERO : mergeStudentRegDetail.getRefundAmount();
            List<Long> recordNum = periodGradeSubjectStudentRecord.get(periodGradeSubjectStudentKey);
            if (totalRefundAmount.equals(studentRegRefund) && mergeStudentRegDetail.getRegStatus() != 0) {
                branchNum = 1;
                if (recordNum != null) {
                    recordNum.remove(mergeStudentRegDetail.getRegId());
                }
            }
            periodGradeSubjectSituationVo.setRealAmount(periodGradeSubjectSituationVo.getRealAmount().subtract(refundAmount));
            if (mergeStudentRegDetail.getStudentState() == 0) {
                periodGradeSubjectSituationVo.setNewStudentAmount(periodGradeSubjectSituationVo.getNewStudentAmount().subtract(refundAmount));
                periodGradeSubjectSituationVo.setNewStudentNum(periodGradeSubjectSituationVo.getNewStudentNum() - branchNum);
                if (branchNum == 1 && (recordNum == null || recordNum.size() == 0)) {
                    periodGradeSubjectSituationVo.setNewStudentPersonNum(periodGradeSubjectSituationVo.getNewStudentPersonNum() - 1);
                }
            } else if (mergeStudentRegDetail.getStudentState() == 1) {
                periodGradeSubjectSituationVo.setOldStudentAmount(periodGradeSubjectSituationVo.getOldStudentAmount().subtract(refundAmount));
                periodGradeSubjectSituationVo.setOldStudentNum(periodGradeSubjectSituationVo.getOldStudentNum() - branchNum);
                if (branchNum == 1 && (recordNum == null || recordNum.size() == 0)) {
                    periodGradeSubjectSituationVo.setOldStudentPersonNum(periodGradeSubjectSituationVo.getOldStudentPersonNum() - 1);
                }
            } else if (mergeStudentRegDetail.getStudentState() == 2) {
                periodGradeSubjectSituationVo.setSeqStepAmount(periodGradeSubjectSituationVo.getSeqStepAmount().subtract(refundAmount));
                periodGradeSubjectSituationVo.setSeqStepNum(periodGradeSubjectSituationVo.getSeqStepNum() - branchNum);
                if (branchNum == 1 && (recordNum == null || recordNum.size() == 0)) {
                    periodGradeSubjectSituationVo.setSeqStepPersonNum(periodGradeSubjectSituationVo.getSeqStepPersonNum() - 1);
                }
            }

        }
    }


    private void fillBusinessSituationMapByReg(BusTeam busTeam,BaseGrade baseGrade,Period period,Map<String,BusinessSituationVo> businessSituationVoMap,Map<String,List<Long>> periodBusTeamGradeStudentRecord,MergeStudentRegDetail mergeStudentRegDetail){
        String periodBusTeamGradeSituationkey=mergeStudentRegDetail.getPeriodId()+"_"+mergeStudentRegDetail.getBusTeamId()+"_"+mergeStudentRegDetail.getGradeId();
        String periodBusTeamGradeStudentKey=periodBusTeamGradeSituationkey+"_"+mergeStudentRegDetail.getStudentId()+"_"+mergeStudentRegDetail.getStudentState();
        BusinessSituationVo businessSituationVo=businessSituationVoMap.get(periodBusTeamGradeSituationkey);
        if (businessSituationVo==null){
            businessSituationVo=new BusinessSituationVo();
            businessSituationVo.setPeriodId(period.getPeriodId());
            businessSituationVo.setPeriodName(period.getPeriodName());
            businessSituationVo.setGradeId(baseGrade.getGradeId());
            businessSituationVo.setGradeName(baseGrade.getGradeName());
            businessSituationVo.setBusTeamName(busTeam.getName());
            businessSituationVo.setBusTeamId(busTeam.getBusTeamId());
            businessSituationVoMap.put(periodBusTeamGradeSituationkey,businessSituationVo);
        }
        BigDecimal realAmount= mergeStudentRegDetail.getPayAmount();
        businessSituationVo.setTotalAmount(businessSituationVo.getTotalAmount().add(mergeStudentRegDetail.getSrcTotalAmount()));
        businessSituationVo.setRealAmount(businessSituationVo.getRealAmount().add(realAmount));
        if (mergeStudentRegDetail.getRegStatus()==0){
            businessSituationVo.setDiscountAmount(businessSituationVo.getDiscountAmount().add(mergeStudentRegDetail.getSrcTotalAmount().subtract(mergeStudentRegDetail.getTotalAmount())));
        }
        switch (mergeStudentRegDetail.getStudentState()){
            case 0:
                businessSituationVo.setNewStudentAmount(businessSituationVo.getNewStudentAmount().add(realAmount));
                businessSituationVo.setNewStudentNum(businessSituationVo.getNewStudentNum() + 1);
                if (!periodBusTeamGradeStudentRecord.containsKey(periodBusTeamGradeStudentKey)){
                    businessSituationVo.setNewStudentPersonNum(businessSituationVo.getNewStudentPersonNum()+1);
                }
                break;
            case 1:
                businessSituationVo.setOldStudentAmount(businessSituationVo.getOldStudentAmount().add(realAmount));
                if (!periodBusTeamGradeStudentRecord.containsKey(periodBusTeamGradeStudentKey)) {
                    businessSituationVo.setOldStudentPersonNum(businessSituationVo.getOldStudentPersonNum() + 1);
                }
                businessSituationVo.setOldStudentNum(businessSituationVo.getOldStudentNum() + 1);
                break;
            case 2:
                businessSituationVo.setSeqStepAmount(businessSituationVo.getSeqStepAmount().add(realAmount));
                if (!periodBusTeamGradeStudentRecord.containsKey(periodBusTeamGradeStudentKey)) {
                    businessSituationVo.setSeqStepPersonNum(businessSituationVo.getSeqStepPersonNum() + 1);
                }
                businessSituationVo.setSeqStepNum(businessSituationVo.getSeqStepNum() + 1);
                break;
            default:
                break;

        }
        List<Long> studentRegIdList = periodBusTeamGradeStudentRecord.get(periodBusTeamGradeStudentKey);
        if (studentRegIdList == null) {
            studentRegIdList = new ArrayList<>();
        }
        studentRegIdList.add(mergeStudentRegDetail.getRegId());
        periodBusTeamGradeStudentRecord.put(periodBusTeamGradeStudentKey, studentRegIdList);
    }

    private void fillBusinessSituationMapByRegRefund(BusTeam busTeam,BaseGrade baseGrade,Period period,Map<String, BusinessSituationVo> businessSituationVoMap, Map<String, List<Long>> periodBusTeamGradeStudentRecord, MergeStudentRegDetail mergeStudentRegDetail, Map<String, List<StudentRefund>> refundRegMap) {
        String periodBusTeamGradeSituationKey = mergeStudentRegDetail.getPeriodId() + "_" + mergeStudentRegDetail.getBusTeamId() + "_" + mergeStudentRegDetail.getGradeId();
        String periodBusTeamGradeStudentKey = periodBusTeamGradeSituationKey + "_" + mergeStudentRegDetail.getStudentId()+"_"+mergeStudentRegDetail.getStudentState();
        BusinessSituationVo businessSituationVo = businessSituationVoMap.get(periodBusTeamGradeSituationKey);
        if (businessSituationVo == null) {
            businessSituationVo = new BusinessSituationVo();
            businessSituationVo.setPeriodId(period.getPeriodId());
            businessSituationVo.setPeriodName(period.getPeriodName());
            businessSituationVo.setGradeId(baseGrade.getGradeId());
            businessSituationVo.setGradeName(baseGrade.getGradeName());
            businessSituationVo.setBusTeamName(busTeam.getName());
            businessSituationVo.setBusTeamId(busTeam.getBusTeamId());
            businessSituationVoMap.put(periodBusTeamGradeSituationKey, businessSituationVo);
        }

        List<StudentRefund> oneStudentRefundList = refundRegMap.get(mergeStudentRegDetail.getStudentId() + "_" + mergeStudentRegDetail.getClassId());
        if (oneStudentRefundList == null) {
            return;
        }
        BigDecimal totalRefundAmount = BigDecimal.ZERO;
        for (StudentRefund studentRefund : oneStudentRefundList) {
            BigDecimal refundAmount = studentRefund.getAmount();
            totalRefundAmount = totalRefundAmount.add(refundAmount);
            Integer branchNum = 0;
            BigDecimal studentRegRefund = mergeStudentRegDetail.getRefundAmount() == null ? BigDecimal.ZERO : mergeStudentRegDetail.getRefundAmount();
            List<Long> recordNum = periodBusTeamGradeStudentRecord.get(periodBusTeamGradeStudentKey);
            if (totalRefundAmount.equals(studentRegRefund) && mergeStudentRegDetail.getRegStatus() != 0) {
                branchNum = 1;
                if (recordNum != null) {
                    recordNum.remove(mergeStudentRegDetail.getRegId());
                }
            }

            businessSituationVo.setRealAmount(businessSituationVo.getRealAmount().subtract(refundAmount));
            if (mergeStudentRegDetail.getStudentState() == 0) {
                businessSituationVo.setNewStudentAmount(businessSituationVo.getNewStudentAmount().subtract(refundAmount));
                businessSituationVo.setNewStudentNum(businessSituationVo.getNewStudentNum() - branchNum);
                if (branchNum == 1 && (recordNum == null || recordNum.size() == 0)) {
                    businessSituationVo.setNewStudentPersonNum(businessSituationVo.getNewStudentPersonNum() - 1);
                }
            } else if (mergeStudentRegDetail.getStudentState() == 1) {
                businessSituationVo.setOldStudentAmount(businessSituationVo.getOldStudentAmount().subtract(refundAmount));
                businessSituationVo.setOldStudentNum(businessSituationVo.getOldStudentNum() - branchNum);
                if (branchNum == 1 && (recordNum == null || recordNum.size() == 0)) {
                    businessSituationVo.setOldStudentPersonNum(businessSituationVo.getOldStudentPersonNum() - 1);
                }
            } else if (mergeStudentRegDetail.getStudentState() == 2) {
                businessSituationVo.setSeqStepAmount(businessSituationVo.getSeqStepAmount().subtract(refundAmount));
                businessSituationVo.setSeqStepNum(businessSituationVo.getSeqStepNum() - branchNum);
                if (branchNum == 1 && (recordNum == null || recordNum.size() == 0)) {
                    businessSituationVo.setSeqStepPersonNum(businessSituationVo.getSeqStepPersonNum() - 1);
                }
            }

        }
    }

    private void fillBusinessSituationMapByTarget(Map<String,BusinessSituationVo> businessSituationVoMap,MainAccountTarget mainAccountTarget,Period period,BusTeam busTeam,BaseGrade baseGrade){
        String periodBusTeamGradeSituationKey = mainAccountTarget.getPeriodId() + "_" + mainAccountTarget.getMainAccountId() + "_" + mainAccountTarget.getGroupId();
        BusinessSituationVo businessSituationVo = businessSituationVoMap.get(periodBusTeamGradeSituationKey);
        if (businessSituationVo == null) {
            businessSituationVo = new BusinessSituationVo();
            businessSituationVo.setPeriodId(period.getPeriodId());
            businessSituationVo.setPeriodName(period.getPeriodName());
            businessSituationVo.setGradeId(baseGrade.getGradeId());
            businessSituationVo.setGradeName(baseGrade.getGradeName());
            businessSituationVo.setBusTeamName(busTeam.getName());
            businessSituationVo.setBusTeamId(busTeam.getBusTeamId());
            businessSituationVoMap.put(periodBusTeamGradeSituationKey, businessSituationVo);
        }
        String numStr = mainAccountTarget.getTargetNum();
        if (numStr !=null && !"".equals(numStr.trim())){
            businessSituationVo.setTargetAmount(new BigDecimal(numStr.trim()));
            businessSituationVo.setAmountRate(Utils.getPercent(businessSituationVo.getRealAmount().toString(),businessSituationVo.getTargetAmount().toString(),2));
        }

    }

    private void fillPeriodGradeSubjectSituationMapByTarget(AreaTeam areaTeam,Map<String, PeriodGradeSubjectSituationVo> periodGradeSubjectSituationVoMap,MainAccountTarget mainAccountTarget,Period period,BaseGrade baseGrade,BaseSubject baseSubject){
        String periodGradeSubjectSituationkey = mainAccountTarget.getPeriodId() + "_" + baseGrade.getGradeId() + "_" + baseSubject.getSubjectId();

        PeriodGradeSubjectSituationVo periodGradeSubjectSituationVo = periodGradeSubjectSituationVoMap.get(periodGradeSubjectSituationkey);
        if (periodGradeSubjectSituationVo == null) {
            periodGradeSubjectSituationVo = new PeriodGradeSubjectSituationVo();
            periodGradeSubjectSituationVo.setPeriodId(period.getPeriodId());
            periodGradeSubjectSituationVo.setPeriodName(period.getPeriodName());
            periodGradeSubjectSituationVo.setGradeId(baseGrade.getGradeId());
            periodGradeSubjectSituationVo.setGradeName(baseGrade.getGradeName());
            periodGradeSubjectSituationVo.setSubjectId(baseSubject.getSubjectId());
            periodGradeSubjectSituationVo.setSubjectName(baseSubject.getSubjectName());
            periodGradeSubjectSituationVo.setAreaTeamId(areaTeam.getAreaTeamId());
            periodGradeSubjectSituationVo.setAreaTeamName(areaTeam.getName());
            periodGradeSubjectSituationVoMap.put(periodGradeSubjectSituationkey, periodGradeSubjectSituationVo);
        }
        String numStr = mainAccountTarget.getTargetNum();
        if (numStr !=null && !"".equals(numStr.trim())){
            periodGradeSubjectSituationVo.setTargetAmount(new BigDecimal(numStr.trim()));
            periodGradeSubjectSituationVo.setAmountRate(Utils.getPercent(periodGradeSubjectSituationVo.getRealAmount().toString(),periodGradeSubjectSituationVo.getTargetAmount().toString(),2));
        }

    }



    @Override
    public SXSSFWorkbook exportBusinessSituation(DataPermission dataPermission,Long areaTeamId, List<Long> busTeamIds, List<Long> periodIds, List<Long> gradeIds,List<Long> subjectIds, Date startDate, Date endDate, int needWithPeriod) {
        SitutaionVo situtaionVo = this.findBusinessSituationList(dataPermission,areaTeamId, busTeamIds, periodIds, gradeIds, subjectIds, startDate, endDate, needWithPeriod, 1);

        List<BusinessSituationVo> businessSituationVoList= situtaionVo.getBusinessSituationVoList();
        SXSSFWorkbook excel=new SXSSFWorkbook();
        businessSituation2excel(businessSituationVoList,excel);
        return periodGradeSubjectSituation2excel(situtaionVo.getPeriodGradeSubjectSituationVoList(),excel);
    }


    @Override
    public BlockVo findBlockVo(DataPermission dataPermission,Long areaTeamId, List<Long> busTeamIds, List<Long> periodIds, List<Long> gradeIds, List<Long> subjectIds,Date startDate, Date endDate) {

        if (endDate==null){
            throw new BusException("请选择报读结束日期");
        }
        if (areaTeamId==null){
            throw new BusException("区域必传");
        }
        if (endDate==null){
            endDate=TimeUtils.changeOneDateLastTime(new Date());
        }

        PerimissionTypeListVo perimissionTypeListVo = this.checkAndFillDataPerssion(dataPermission, areaTeamId, busTeamIds, gradeIds, subjectIds);
        busTeamIds=perimissionTypeListVo.getBusTeamIds();
        gradeIds=perimissionTypeListVo.getGradeIds();
        subjectIds=perimissionTypeListVo.getSubjectIds();


        endDate= TimeUtils.changeOneDateLastTime(endDate);

        List<AdvanceBlockVo> advanceBlockVoList=new ArrayList<>();
        List<StudentStateBlockVo> studentStateBlockVoList=new ArrayList<>();
        List<BranchNumBlockVo> branchNumBlockVoList=new ArrayList<>();
        List<Period> periodList=periodService.findByIdsOrderByPeriodNo(periodIds);
        List<BusTeam> busTeamList=busTeamService.findByIds(busTeamIds);

        PeriodRegVo periodRegVo=this.findPeriodAndWithPeriod(areaTeamId,busTeamIds,periodIds,gradeIds,subjectIds,startDate,endDate,Arrays.asList(0,3),1,1);
        List<MergeStudentRegDetail> mergeStudentRegDetailList =periodRegVo.getMergeStudentRegDetailList();
        List<BaseGrade> baseGradeList=null;
        if (Utils.checkListNotEmpty(gradeIds)){
            baseGradeList=baseGradeService.findDealOtherPosition(gradeIds);
        }else {
            baseGradeList=baseGradeService.findAllOrderGrade();
        }
        List<BaseSubject> baseSubjectList=null;
        if (Utils.checkListNotEmpty(subjectIds)){
            baseSubjectList=baseSubjectService.findByIds(subjectIds);
        }else {
            baseSubjectList=baseSubjectService.findAllFromCache();
        }
        List<TargetTypeVo> targetTypeVoList=this.toListByGradeSubjectKey(baseGradeList,baseSubjectList,"99");
        List<String> targetTypes = BeanUtils.toList(targetTypeVoList, "targetType");
        List<MainAccountTarget> subjectMainAccountTargetList=mainAccountTargetService.findListByMainAccountIdAndPeriodIds(areaTeamId,periodIds,null,targetTypes);
        Map<Long,List<MainAccountTarget>> periodSubjectTargetMap=BeanUtils.toGroup(subjectMainAccountTargetList,"periodId");


        AreaTeam areaTeam=areaTeamService.findById(areaTeamId);

        Map<Long,List<MergeStudentRegDetail>> periodStudentRegMap=BeanUtils.toGroup(mergeStudentRegDetailList,"periodId");


        List<Period> allPeriod=periodRegVo.getPeriodList();
        List<Long> allPeriodIds=BeanUtils.toList(allPeriod,"periodId");
        List<MainAccountTarget> mainAccountTargetList=mainAccountTargetService.findByGroupId(busTeamIds,gradeIds,allPeriodIds);
        Map<Long,List<MainAccountTarget>> periodTargetMap=BeanUtils.toGroup(mainAccountTargetList,"periodId");
        List<StudentRefund> studentRefundList=periodRegVo.getStudentRefundList();
        Map<String,List<StudentRefund>> periodGradeStudentRefundMap=new HashMap<>();
        if (studentRefundList!=null){
            for (StudentRefund studentRefund:studentRefundList){
                String key=studentRefund.getPeriodId()+"_"+studentRefund.getGradeId();
                List<StudentRefund> periodGradeStudentRefundList=periodGradeStudentRefundMap.get(key);
                if (periodGradeStudentRefundList==null){
                    periodGradeStudentRefundList=new ArrayList<>();
                    periodGradeStudentRefundMap.put(key,periodGradeStudentRefundList);
                }
                periodGradeStudentRefundList.add(studentRefund);
            }
        }

        for (Period period:periodList){
            List<MergeStudentRegDetail> periodStudentRegList=periodStudentRegMap.get(period.getPeriodId());

            List<MergeStudentRegDetail> withPeriodStudentRegList=periodStudentRegMap.get(period.getWithPeriodId());

            List<MainAccountTarget> periodTargetList=periodTargetMap.get(period.getPeriodId());

            List<MainAccountTarget> withPeriodTargetList=periodTargetMap.get(period.getWithPeriodId());

            List<MainAccountTarget> periodSubjectTargetList=periodSubjectTargetMap.get(period.getPeriodId());

            Map<Long,List<MergeStudentRegDetail>> periodGradeStudentRegMap=BeanUtils.toGroup(periodStudentRegList,"gradeId");

            Map<Long,List<MergeStudentRegDetail>> withPeriodGradeStudentRegMap=BeanUtils.toGroup(withPeriodStudentRegList,"gradeId");

            Map<Long,List<MainAccountTarget>> periodGradeTargetMap=BeanUtils.toGroup(periodTargetList,"groupId");

            Map<Long,List<MainAccountTarget>> periodGradeSubjectTargetMap=BeanUtils.toGroup(periodSubjectTargetList,"groupId");

            Map<Long,List<MainAccountTarget>> withPeriodGradeTargetMap=BeanUtils.toGroup(withPeriodTargetList,"groupId");
            Map<Long,BusTeam> map=BeanUtils.toMap(busTeamList,"busTeamId");
            for (BaseGrade baseGrade:baseGradeList){
                Long gradeId=baseGrade.getGradeId();

                String refundkey=period.getPeriodId()+"_"+gradeId;
                String withRefundKey=period.getWithPeriodId()+"_"+gradeId;

                List<StudentRefund> periodGradeStudentRefundList=periodGradeStudentRefundMap.get(refundkey);

                List<StudentRefund> withPeriodGradeStudentRefundList=periodGradeStudentRefundMap.get(withRefundKey);

                List<MergeStudentRegDetail> periodGradeStudentRegList=periodGradeStudentRegMap.get(gradeId)==null?Collections.EMPTY_LIST:periodGradeStudentRegMap.get(gradeId);
                List<MergeStudentRegDetail> withPeriodGradeStudentRegList=withPeriodGradeStudentRegMap.get(gradeId)==null?Collections.EMPTY_LIST:withPeriodGradeStudentRegMap.get(gradeId);



                advanceBlockVoList.add(this.toAdvanceBlock(areaTeam,period,baseGrade,periodGradeTargetMap,withPeriodGradeTargetMap,periodGradeSubjectTargetMap,map,withPeriodGradeStudentRegList,periodGradeStudentRefundList,periodGradeStudentRegList,withPeriodGradeStudentRefundList )) ;
                studentStateBlockVoList.add(this.toStudentStateBlockVo(areaTeam,period,baseGrade,periodGradeStudentRegList,withPeriodGradeStudentRegList,map));
                branchNumBlockVoList.add(this.toBranchNumBlockVo(areaTeam, period, baseGrade, periodGradeStudentRegList));

            }
        }
        BlockVo blockVo=new BlockVo();
        blockVo.setAdvanceBlockVoList(advanceBlockVoList);
        blockVo.setStudentStateBlockVoList(studentStateBlockVoList);
        blockVo.setBranchNumBlockVoList(branchNumBlockVoList);
        return blockVo;
    }

    private List<TargetTypeVo> toListByGradeSubjectKey(List<BaseGrade> baseGradeList,List<BaseSubject> baseSubjectList,String key){
        List<TargetTypeVo> targetTypeVoList=new ArrayList<>(baseGradeList.size()*baseSubjectList.size());
        for (BaseGrade baseGrade:baseGradeList){
            for (BaseSubject baseSubject:baseSubjectList){
                TargetTypeVo targetTypeVo=new TargetTypeVo();
                targetTypeVo.setGroupId(baseGrade.getGradeId());
                targetTypeVo.setGroupName(baseGrade.getGradeName());
                targetTypeVo.setTargetName(baseSubject.getSubjectName()+"预收");
                targetTypeVo.setType(1);
                targetTypeVo.setTargetType(baseGrade.getGradeId().toString()+"-"+baseSubject.getSubjectId().toString()+"-"+key);
                targetTypeVoList.add(targetTypeVo);
            }
        }
        return targetTypeVoList;
    }

    @Override
    public List<AdvanceBlockVo> findAdvanceBlock(DataPermission dataPermission,Long areaTeamId, List<Long> busTeamIds, List<Long> periodIds, List<Long> gradeIds,List<Long> subjectIds, Date startDate, Date endDate) {
        if (endDate == null) {
            throw new BusException("请选择报读结束日期");
        }
        endDate = TimeUtils.changeOneDateLastTime(endDate);

        PerimissionTypeListVo perimissionTypeListVo = this.checkAndFillDataPerssion(dataPermission, areaTeamId, busTeamIds, gradeIds, subjectIds);
        busTeamIds=perimissionTypeListVo.getBusTeamIds();
        gradeIds=perimissionTypeListVo.getGradeIds();
        subjectIds=perimissionTypeListVo.getSubjectIds();

        List<AdvanceBlockVo> advanceBlockVoList = new ArrayList<>();
        List<Period> periodList = periodService.findByIdsOrderByPeriodNo(periodIds);
        PeriodRegVo periodRegVo = this.findPeriodAndWithPeriod(areaTeamId, busTeamIds, periodIds, gradeIds,subjectIds, startDate, endDate,Arrays.asList(0,3), 1,1);
        List<MergeStudentRegDetail> mergeStudentRegDetailList = periodRegVo.getMergeStudentRegDetailList();
        List<BaseGrade> baseGradeList = periodRegVo.getBaseGradeList();
        AreaTeam areaTeam = areaTeamService.findById(areaTeamId);

        Map<Long, List<MergeStudentRegDetail>> periodStudentRegMap = BeanUtils.toGroup(mergeStudentRegDetailList, "periodId");
        List<Period> allPeriod = periodRegVo.getPeriodList();
        List<Long> allPeriodIds = BeanUtils.toList(allPeriod, "periodId");
        List<MainAccountTarget> mainAccountTargetList = mainAccountTargetService.findByGroupId(busTeamIds, gradeIds, allPeriodIds);
        Map<Long, List<MainAccountTarget>> periodTargetMap = BeanUtils.toGroup(mainAccountTargetList, "periodId");
        List<BusTeam> busTeamList=busTeamService.findByIds(busTeamIds);
        Map<Long,BusTeam> map=BeanUtils.toMap(busTeamList,"busTeamId");

        List<StudentRefund> studentRefundList=periodRegVo.getStudentRefundList();
        Map<String,List<StudentRefund>> periodGradeStudentRefundMap=new HashMap<>();
        if (studentRefundList!=null){
            for (StudentRefund studentRefund:studentRefundList){
                String key=studentRefund.getPeriodId()+"_"+studentRefund.getGradeId();
                List<StudentRefund> periodGradeStudentRefundList=periodGradeStudentRefundMap.get(key);
                if (periodGradeStudentRefundList==null){
                    periodGradeStudentRefundList=new ArrayList<>();
                    periodGradeStudentRefundMap.put(key,periodGradeStudentRefundList);
                }
                periodGradeStudentRefundList.add(studentRefund);
            }
        }


        for (Period period : periodList) {
            List<MergeStudentRegDetail> periodStudentRegList = periodStudentRegMap.get(period.getPeriodId());
            List<MergeStudentRegDetail> withPeriodStudentRegList = periodStudentRegMap.get(period.getWithPeriodId());
            List<MainAccountTarget> periodTargetList = periodTargetMap.get(period.getPeriodId());
            List<MainAccountTarget> withPeriodTargetList = periodTargetMap.get(period.getWithPeriodId());

            Map<Long, List<MergeStudentRegDetail>> periodGradeStudentRegMap = BeanUtils.toGroup(periodStudentRegList, "gradeId");
            Map<Long, List<MergeStudentRegDetail>> withPeriodGradeStudentRegMap = BeanUtils.toGroup(withPeriodStudentRegList, "gradeId");
            Map<Long, List<MainAccountTarget>> periodGradeTargetMap = BeanUtils.toGroup(periodTargetList, "groupId");
            Map<Long, List<MainAccountTarget>> withPeriodGradeTargetMap = BeanUtils.toGroup(withPeriodTargetList, "groupId");
            for (BaseGrade baseGrade : baseGradeList) {
                Long gradeId = baseGrade.getGradeId();
                List<MergeStudentRegDetail> periodGradeStudentRegList = periodGradeStudentRegMap.get(gradeId) == null ? Collections.EMPTY_LIST : periodGradeStudentRegMap.get(gradeId);
                List<MergeStudentRegDetail> withPeriodGradeStudentRegList = withPeriodGradeStudentRegMap.get(gradeId) == null ? Collections.EMPTY_LIST : withPeriodGradeStudentRegMap.get(gradeId);
            /*    if (periodGradeStudentRegList.size()<=0 && withPeriodGradeStudentRegList.size()<=0){
                    continue;
                }*/
                String refundkey=period.getPeriodId()+"_"+gradeId;
                String withRefundKey=period.getWithPeriodId()+"_"+gradeId;

                List<StudentRefund> periodGradeStudentRefundList=periodGradeStudentRefundMap.get(refundkey);

                List<StudentRefund> withPeriodGradeStudentRefundList=periodGradeStudentRefundMap.get(withRefundKey);

                AdvanceBlockVo advanceBlockVo=this.toAdvanceBlock( areaTeam, period, baseGrade,periodGradeTargetMap,withPeriodGradeTargetMap,new HashMap<>(), map,withPeriodGradeStudentRegList,periodGradeStudentRefundList,periodGradeStudentRegList, withPeriodGradeStudentRefundList );
                advanceBlockVoList.add(advanceBlockVo);
            }
        }
        return advanceBlockVoList;
    }



    public AdvanceBlockVo toAdvanceBlock(AreaTeam areaTeam,Period period,BaseGrade baseGrade,Map<Long,List<MainAccountTarget>> periodGradeTargetMap,Map<Long,List<MainAccountTarget>> withPeriodGradeTargetMap,Map<Long,List<MainAccountTarget>> periodGradeSubjectTargetMap,Map<Long,BusTeam> map,List<MergeStudentRegDetail> withPeriodGradeStudentRegList,List<StudentRefund> periodGradeStudentRefundList,List<MergeStudentRegDetail> periodGradeStudentRegList,List<StudentRefund> withPeriodGradeStudentRefundList ) {
        Map<Long,AdvanceDetailVo> advanceDetailVoMap=new HashMap<>();
        AdvanceBlockVo advanceBlockVo = new AdvanceBlockVo();
        Long areaTeamId=areaTeam.getAreaTeamId();
        Long gradeId=baseGrade.getGradeId();
        Long periodId=period.getPeriodId();
        advanceBlockVo.setAreaTeamId(areaTeamId);
        advanceBlockVo.setAreaTeamName(areaTeam.getName());
        advanceBlockVo.setPeriodId(periodId);
        advanceBlockVo.setPeriodName(period.getPeriodName());
        advanceBlockVo.setGradeId(gradeId);
        advanceBlockVo.setGradeName(baseGrade.getGradeName());
        List<MainAccountTarget> periodGradeTargetList = periodGradeTargetMap.get(gradeId) == null ? Collections.EMPTY_LIST : periodGradeTargetMap.get(gradeId);
        List<MainAccountTarget> withPeriodGradeTargetList = withPeriodGradeTargetMap.get(gradeId) == null ? Collections.EMPTY_LIST : withPeriodGradeTargetMap.get(gradeId);
        List<MainAccountTarget>  periodGradeSubjectTargetList=periodGradeSubjectTargetMap.get(gradeId);
        for (MainAccountTarget mainAccountTarget : periodGradeTargetList) {
            String fullTargetType = mainAccountTarget.getTargetType();
            String targetType = fullTargetType.substring(fullTargetType.length()-2,fullTargetType.length());
            String numStr = mainAccountTarget.getTargetNum();
            if (numStr == null || "".equals(numStr.trim())) {
                continue;
            }
            if (TargetTypeEnum.CLASS_INCOME.id.equals(targetType)) {
                BigDecimal amount=new BigDecimal(numStr.trim());
                advanceBlockVo.setTargetAmount(advanceBlockVo.getTargetAmount().add(amount));
                AdvanceDetailVo advanceDetailVo=advanceDetailVoMap.get(mainAccountTarget.getMainAccountId());
                if (advanceDetailVo==null){
                    advanceDetailVo=new AdvanceDetailVo();
                    advanceDetailVo.setBusTeamId(mainAccountTarget.getMainAccountId());
                    BusTeam busTeam=map.get(mainAccountTarget.getMainAccountId());
                    advanceDetailVo.setBusTeamName(busTeam==null?"":busTeam.getName());
                }
                advanceDetailVo.setTargetAmount(advanceDetailVo.getTargetAmount().add(amount));
                advanceDetailVoMap.put(mainAccountTarget.getMainAccountId(),advanceDetailVo);
            }
        }
        if (withPeriodGradeTargetList != null) {
            for (MainAccountTarget mainAccountTarget : withPeriodGradeTargetList) {
                String fullTargetType = mainAccountTarget.getTargetType();
                String targetType = fullTargetType.substring(fullTargetType.length()-2,fullTargetType.length());
                String numStr = mainAccountTarget.getTargetNum();
                if (numStr == null || "".equals(numStr.trim())) {
                    continue;
                }
                if (TargetTypeEnum.CLASS_INCOME.id.equals(targetType)) {
                    advanceBlockVo.setWithTargetAmount(advanceBlockVo.getWithTargetAmount().add(new BigDecimal(numStr.trim())));
                }
            }
        }
        if (periodGradeSubjectTargetList!=null){
            for (MainAccountTarget mainAccountTarget:periodGradeSubjectTargetList){
                String numStr = mainAccountTarget.getTargetNum();
                if (numStr ==null || "".equals(numStr.trim())){
                    continue;
                }
                advanceBlockVo.setSubjectTarget(advanceBlockVo.getSubjectTarget().add(new BigDecimal(numStr.trim())));
            }
        }

        for (MergeStudentRegDetail mergeStudentRegDetail : periodGradeStudentRegList) {
            if (mergeStudentRegDetail.getStudentState()==null){
                continue;
            }
            BigDecimal realAmount= mergeStudentRegDetail.getPayAmount();
            advanceBlockVo.setAdvanceAmount(advanceBlockVo.getAdvanceAmount().add(realAmount));
            AdvanceDetailVo advanceDetailVo=advanceDetailVoMap.get(mergeStudentRegDetail.getBusTeamId());
            if (advanceDetailVo==null){
                advanceDetailVo=new AdvanceDetailVo();
                advanceDetailVo.setBusTeamId(mergeStudentRegDetail.getBusTeamId());
                BusTeam busTeam=map.get(mergeStudentRegDetail.getBusTeamId());
                advanceDetailVo.setBusTeamName(busTeam==null?"":busTeam.getName());
            }
            advanceDetailVo.setAdvanceAmount(advanceDetailVo.getAdvanceAmount().add(realAmount));
            advanceDetailVo.setAdvanceProgress(Utils.getPercent(advanceDetailVo.getAdvanceAmount().toString(),advanceDetailVo.getTargetAmount().toString(),2));
            advanceDetailVoMap.put(mergeStudentRegDetail.getBusTeamId(),advanceDetailVo);
        }
        if (withPeriodGradeStudentRegList != null) {
            for (MergeStudentRegDetail mergeStudentRegDetail : withPeriodGradeStudentRegList) {
                BigDecimal realAmount= mergeStudentRegDetail.getPayAmount();
                advanceBlockVo.setWithAdvanceAmount(advanceBlockVo.getWithAdvanceAmount().add(realAmount));
            }
        }
        if (periodGradeStudentRefundList!=null){
            for (StudentRefund studentRefund:periodGradeStudentRefundList){
                advanceBlockVo.setAdvanceAmount(advanceBlockVo.getAdvanceAmount().subtract(studentRefund.getAmount()));
                AdvanceDetailVo advanceDetailVo = advanceDetailVoMap.get(studentRefund.getBusTeamId());
                advanceDetailVo.setAdvanceAmount(advanceDetailVo.getAdvanceAmount().subtract(studentRefund.getAmount()));
                advanceDetailVo.setAdvanceProgress(Utils.getPercent(advanceDetailVo.getAdvanceAmount().toString(),advanceDetailVo.getTargetAmount().toString(),2));
            }
        }
        if (withPeriodGradeStudentRefundList!=null){
            for (StudentRefund studentRefund:withPeriodGradeStudentRefundList){
                advanceBlockVo.setWithAdvanceAmount(advanceBlockVo.getWithAdvanceAmount().subtract(studentRefund.getAmount()));
            }
        }

        advanceBlockVo.setAdvanceProgress(Utils.getPercent(advanceBlockVo.getAdvanceAmount().toString(), advanceBlockVo.getTargetAmount().toString(), 2));
        advanceBlockVo.setWithProgress(Utils.getPercent(advanceBlockVo.getWithAdvanceAmount().toString(), advanceBlockVo.getWithTargetAmount().toString(), 2));
        advanceBlockVo.setAdvanceCompare(Utils.getPercent((advanceBlockVo.getAdvanceAmount().subtract(advanceBlockVo.getWithAdvanceAmount())).toString(), advanceBlockVo.getWithAdvanceAmount().toString(), 2));
        advanceBlockVo.setTargetCompare(Utils.getPercent((advanceBlockVo.getTargetAmount().subtract(advanceBlockVo.getWithAdvanceAmount())).toString(), advanceBlockVo.getWithAdvanceAmount().toString(), 2));
        advanceBlockVo.setSubjectTargetProgress(Utils.getPercent(advanceBlockVo.getAdvanceAmount().toString(),advanceBlockVo.getSubjectTarget().toString(),2));
        Collection<AdvanceDetailVo> advanceDetailVos = advanceDetailVoMap.values();
        List<AdvanceDetailVo> advanceDetailVoList=new ArrayList<>(advanceDetailVos);
        advanceBlockVo.setAdvanceDetailVoList(advanceDetailVoList);
        return advanceBlockVo;
    }

    @Override
    @Cacheable(value = "CacheOfBusTeamPeriodAdvance",key = "#areaTeamId+'_'+#busTeamId+'_'+#periodId+'_'+#endDate")
    public BusTeamPeriodAdvanceVo findBusTeamPeriodAdvance(long areaTeamId, long busTeamId, long periodId,String endDate) {
        BusTeamPeriodAdvanceVo busTeamPeriodAdvanceVo=new BusTeamPeriodAdvanceVo();
        busTeamPeriodAdvanceVo.setBusTeamId(busTeamId);
        busTeamPeriodAdvanceVo.setPeriodId(periodId);
        List<AdvanceBlockVo> advanceBlockVoList=this.findAdvanceBlock(null,areaTeamId,Arrays.asList(busTeamId),Arrays.asList(periodId),null,null,null,TimeUtils.changeOneDateLastTime(Utils.parseDate(endDate,"yyyy-MM-dd")));
        if (Utils.checkListNotEmpty(advanceBlockVoList)){
            for (AdvanceBlockVo advanceBlockVo:advanceBlockVoList){
                busTeamPeriodAdvanceVo.setAdvanceAmount(busTeamPeriodAdvanceVo.getAdvanceAmount().add(advanceBlockVo.getAdvanceAmount()));
                busTeamPeriodAdvanceVo.setTargetAmount(busTeamPeriodAdvanceVo.getTargetAmount().add(advanceBlockVo.getTargetAmount()));
                busTeamPeriodAdvanceVo.setWithAdvanceAmount(busTeamPeriodAdvanceVo.getWithAdvanceAmount().add(advanceBlockVo.getWithAdvanceAmount()));
                busTeamPeriodAdvanceVo.setWithTargetAmount(busTeamPeriodAdvanceVo.getWithTargetAmount().add(advanceBlockVo.getWithTargetAmount()));
            }
        }
        return busTeamPeriodAdvanceVo;
    }

    @Override
    public List<StudentStateBlockVo> findStudentStateBlock(DataPermission dataPermission,Long areaTeamId, List<Long> busTeamIds, List<Long> periodIds, List<Long> gradeIds,List<Long> subjectIds, Date startDate, Date endDate) {
        if (endDate==null){
            throw new BusException("请选择报读结束日期");
        }
        endDate= TimeUtils.changeOneDateLastTime(endDate);
        PerimissionTypeListVo perimissionTypeListVo = this.checkAndFillDataPerssion(dataPermission, areaTeamId, busTeamIds, gradeIds, subjectIds);
        busTeamIds=perimissionTypeListVo.getBusTeamIds();
        gradeIds=perimissionTypeListVo.getGradeIds();
        subjectIds=perimissionTypeListVo.getSubjectIds();

        List<StudentStateBlockVo> studentStateBlockVoList=new ArrayList<>();
        List<Period> periodList=periodService.findByIdsOrderByPeriodNo(periodIds);
        PeriodRegVo periodRegVo=this.findPeriodAndWithPeriod(areaTeamId,busTeamIds,periodIds,gradeIds,subjectIds,startDate,endDate,Arrays.asList(0),1,0);
        List<MergeStudentRegDetail> mergeStudentRegDetailList =periodRegVo.getMergeStudentRegDetailList();
        List<BaseGrade> baseGradeList=periodRegVo.getBaseGradeList();
        AreaTeam areaTeam=areaTeamService.findById(areaTeamId);
        List<BusTeam> busTeamList=busTeamService.findByIds(busTeamIds);
        Map<Long,BusTeam> map=BeanUtils.toMap(busTeamList,"busTeamId");
        Map<Long,List<MergeStudentRegDetail>> periodStudentRegMap=BeanUtils.toGroup(mergeStudentRegDetailList,"periodId");
        for (Period period:periodList){
            List<MergeStudentRegDetail> periodStudentRegList=periodStudentRegMap.get(period.getPeriodId());
            List<MergeStudentRegDetail> withPeriodStudentRegList=periodStudentRegMap.get(period.getWithPeriodId());

            Map<Long,List<MergeStudentRegDetail>> periodGradeStudentRegMap=BeanUtils.toGroup(periodStudentRegList,"gradeId");
            Map<Long,List<MergeStudentRegDetail>> withPeriodGradeStudentRegMap=BeanUtils.toGroup(withPeriodStudentRegList,"gradeId");
            for (BaseGrade baseGrade:baseGradeList){
                Long gradeId=baseGrade.getGradeId();
                List<MergeStudentRegDetail> periodGradeStudentRegList=periodGradeStudentRegMap.get(gradeId)==null?Collections.EMPTY_LIST:periodGradeStudentRegMap.get(gradeId);
                List<MergeStudentRegDetail> withPeriodGradeStudentRegList=withPeriodGradeStudentRegMap.get(gradeId)==null?Collections.EMPTY_LIST:withPeriodGradeStudentRegMap.get(gradeId);

                studentStateBlockVoList.add(this.toStudentStateBlockVo(areaTeam,period,baseGrade,periodGradeStudentRegList,withPeriodGradeStudentRegList,map));
            }
        }
        return studentStateBlockVoList;
    }

    private  StudentStateBlockVo toStudentStateBlockVo(AreaTeam areaTeam,Period period,BaseGrade baseGrade,List<MergeStudentRegDetail> periodGradeStudentRegList,List<MergeStudentRegDetail> withPeriodGradeStudentRegList,Map<Long,BusTeam> map){
        periodGradeStudentRegList=periodGradeStudentRegList.stream().filter(item->item.getRegStatus().equals(0)).collect(Collectors.toList());
        withPeriodGradeStudentRegList=withPeriodGradeStudentRegList.stream().filter(item->item.getRegStatus().equals(0)).collect(Collectors.toList());
        Map<String,Integer> recordStudentRegNum=new HashMap<>();
        Map<String,Integer> withRecordStudentRegNum=new HashMap<>();
        Map<Long,StudentStateDetailVo> studentStateDetailVoMap=new HashMap<>();

        Long areaTeamId=areaTeam.getAreaTeamId();
        String areaTeamName=areaTeam.getName();
        Long periodId=period.getPeriodId();
        String periodName=period.getPeriodName();
        Long gradeId=baseGrade.getGradeId();
        String gradeName=baseGrade.getGradeName();
        StudentStateBlockVo studentStateBlockVo=new StudentStateBlockVo();
        studentStateBlockVo.setAreaTeamId(areaTeamId);
        studentStateBlockVo.setAreaTeamName(areaTeamName);
        studentStateBlockVo.setPeriodId(periodId);
        studentStateBlockVo.setPeriodName(periodName);
        studentStateBlockVo.setGradeId(gradeId);
        studentStateBlockVo.setGradeName(gradeName);

        for (MergeStudentRegDetail mergeStudentRegDetail :periodGradeStudentRegList) {

            String key= mergeStudentRegDetail.getBusTeamId()+"_"+ mergeStudentRegDetail.getStudentId();;
            Long busTeamId= mergeStudentRegDetail.getBusTeamId();
            if (!recordStudentRegNum.containsKey(key)){

                StudentStateDetailVo studentStateDetailVo=studentStateDetailVoMap.get(busTeamId);
                if (studentStateDetailVo==null){
                    studentStateDetailVo=new StudentStateDetailVo();
                    studentStateDetailVo.setBusTeamId(mergeStudentRegDetail.getBusTeamId());
                    BusTeam busTeam=map.get(mergeStudentRegDetail.getBusTeamId());
                    studentStateDetailVo.setBusTeamName(busTeam==null?"":busTeam.getName());
                }
                studentStateDetailVo.setRegStudentNum(studentStateDetailVo.getRegStudentNum()+1);
                studentStateBlockVo.setRegStudentNum(studentStateBlockVo.getRegStudentNum()+1);
                if (mergeStudentRegDetail.getStudentState()==0){
                    studentStateBlockVo.setNewStudentNum(studentStateBlockVo.getNewStudentNum()+1);
                    studentStateDetailVo.setNewStudentNum(studentStateDetailVo.getNewStudentNum()+1);
                }else if (mergeStudentRegDetail.getStudentState()==1){
                    studentStateBlockVo.setOldStudentNum(studentStateBlockVo.getOldStudentNum()+1);
                    studentStateDetailVo.setOldStudentNum(studentStateDetailVo.getOldStudentNum()+1);
                }else if (mergeStudentRegDetail.getStudentState()==2){
                    studentStateBlockVo.setSeqStepStudentNum(studentStateBlockVo.getSeqStepStudentNum()+1);
                    studentStateDetailVo.setSeqStepStudentNum(studentStateDetailVo.getSeqStepStudentNum()+1);
                }
                studentStateDetailVoMap.put(busTeamId,studentStateDetailVo);
                recordStudentRegNum.put(key,1);

            }else {
                recordStudentRegNum.put(key,recordStudentRegNum.get(key)+1);
            }
        }
        if (withPeriodGradeStudentRegList!=null){
            for (MergeStudentRegDetail mergeStudentRegDetail :withPeriodGradeStudentRegList){

                Long busTeamId= mergeStudentRegDetail.getBusTeamId();
                String key= mergeStudentRegDetail.getBusTeamId()+"_"+ mergeStudentRegDetail.getStudentId();;
                StudentStateDetailVo studentStateDetailVo=studentStateDetailVoMap.get(busTeamId);
                if (studentStateDetailVo==null){
                    studentStateDetailVo=new StudentStateDetailVo();
                    studentStateDetailVo.setBusTeamId(mergeStudentRegDetail.getBusTeamId());
                    BusTeam busTeam=map.get(mergeStudentRegDetail.getBusTeamId());
                    studentStateDetailVo.setBusTeamName(busTeam==null?"":busTeam.getName());
                }
                if (!withRecordStudentRegNum.containsKey(key)){
                    studentStateBlockVo.setWithStudentNum(studentStateBlockVo.getWithStudentNum()+1);
                    studentStateDetailVo.setWithStudentNum(studentStateDetailVo.getWithStudentNum()+1);
                    if (mergeStudentRegDetail.getStudentState()==0){
                        studentStateBlockVo.setWithNewStudentNum(studentStateBlockVo.getWithNewStudentNum()+1);
                        studentStateDetailVo.setWithNewStudentNum(studentStateDetailVo.getWithNewStudentNum()+1);
                    }else if (mergeStudentRegDetail.getStudentState()==1){
                        studentStateBlockVo.setWithOldStudentNum(studentStateBlockVo.getWithOldStudentNum()+1);
                        studentStateDetailVo.setWithOldStudentNum(studentStateDetailVo.getWithOldStudentNum()+1);
                    }else if (mergeStudentRegDetail.getStudentState()==2){
                        studentStateBlockVo.setWithSeqStepStudentNum(studentStateBlockVo.getWithSeqStepStudentNum()+1);
                        studentStateDetailVo.setWithSeqStepStudentNum(studentStateDetailVo.getWithSeqStepStudentNum()+1);
                    }
                    withRecordStudentRegNum.put(key,1);
                    studentStateDetailVoMap.put(busTeamId,studentStateDetailVo);
                }else {
                    withRecordStudentRegNum.put(key,withRecordStudentRegNum.get(key)+1);
                }
            }
        }
        Collection<StudentStateDetailVo> studentStateDetailVos = studentStateDetailVoMap.values();
        List<StudentStateDetailVo> studentStateDetailVoList=new ArrayList<>(studentStateDetailVos);
        studentStateBlockVo.setStudentStateDetailVoList(studentStateDetailVoList);
        return studentStateBlockVo;
    }

    @Override
    @Cacheable(value = "CacheOfBusTeamPeriodStudentNum",key = "#areaTeamId+'_'+#busTeamId+'_'+#periodId+'_'+#endDate")
    public BusTeamPeriodStudentNumVo findBusTeamPeriodStudentNum(long areaTeamId, long busTeamId, long periodId, String endDate) {
        BusTeamPeriodStudentNumVo busTeamPeriodStudentNumVo=new BusTeamPeriodStudentNumVo();
        busTeamPeriodStudentNumVo.setBusTeamId(busTeamId);
        busTeamPeriodStudentNumVo.setPeriodId(periodId);
        List<StudentStateBlockVo> studentStateBlockVoList=this.findStudentStateBlock(null,areaTeamId,Arrays.asList(busTeamId),Arrays.asList(periodId),null,null,null,TimeUtils.changeOneDateLastTime(Utils.parseDate(endDate,"yyyy-MM-dd")));
        if (Utils.checkListNotEmpty(studentStateBlockVoList)){
            for (StudentStateBlockVo studentStateBlockVo:studentStateBlockVoList){
                busTeamPeriodStudentNumVo.setRegStudentNum(busTeamPeriodStudentNumVo.getRegStudentNum()+studentStateBlockVo.getRegStudentNum());
                busTeamPeriodStudentNumVo.setWithStudentNum(busTeamPeriodStudentNumVo.getWithStudentNum()+studentStateBlockVo.getWithStudentNum());
            }
        }
        return busTeamPeriodStudentNumVo;
    }

    @Override
    public  List<BranchNumBlockVo> findBranchNumBlockVo(DataPermission dataPermission,Long areaTeamId, List<Long> busTeamIds, List<Long> periodIds, List<Long> gradeIds, List<Long> subjectIds,Date startDate, Date endDate) {
        if (endDate==null){
            throw new BusException("请选择报读结束日期");
        }
        endDate= TimeUtils.changeOneDateLastTime(endDate);
        PerimissionTypeListVo perimissionTypeListVo = this.checkAndFillDataPerssion(dataPermission, areaTeamId, busTeamIds, gradeIds, subjectIds);
        busTeamIds=perimissionTypeListVo.getBusTeamIds();
        gradeIds=perimissionTypeListVo.getGradeIds();
        subjectIds=perimissionTypeListVo.getSubjectIds();
        List<BranchNumBlockVo> branchNumBlockVoList=new ArrayList<>();
        List<Period> periodList=periodService.findByIdsOrderByPeriodNo(periodIds);
        PeriodRegVo periodRegVo=this.findPeriodAndWithPeriod(areaTeamId,busTeamIds,periodIds,gradeIds,subjectIds,startDate,endDate,Arrays.asList(0),0,0);
        List<MergeStudentRegDetail> mergeStudentRegDetailList =periodRegVo.getMergeStudentRegDetailList();

        List<BaseGrade> baseGradeList=periodRegVo.getBaseGradeList();
        AreaTeam areaTeam=areaTeamService.findById(areaTeamId);
        Map<Long,List<MergeStudentRegDetail>> periodStudentRegMap=BeanUtils.toGroup(mergeStudentRegDetailList,"periodId");
        for (Period period:periodList){
            List<MergeStudentRegDetail> periodStudentRegList=periodStudentRegMap.get(period.getPeriodId());

            Map<Long,List<MergeStudentRegDetail>> periodGradeStudentRegMap=BeanUtils.toGroup(periodStudentRegList,"gradeId");
            for (BaseGrade baseGrade:baseGradeList){
                Long gradeId = baseGrade.getGradeId();
                List<MergeStudentRegDetail> periodGradeStudentRegList = periodGradeStudentRegMap.get(gradeId) == null ? Collections.EMPTY_LIST : periodGradeStudentRegMap.get(gradeId);
                branchNumBlockVoList.add(this.toBranchNumBlockVo(areaTeam, period, baseGrade, periodGradeStudentRegList));

            }
        }
        return branchNumBlockVoList;
    }

    private BranchNumBlockVo toBranchNumBlockVo(AreaTeam areaTeam,Period period,BaseGrade baseGrade,List<MergeStudentRegDetail> periodGradeStudentRegList){
        periodGradeStudentRegList=periodGradeStudentRegList.stream().filter(item->item.getRegStatus().equals(0)).collect(Collectors.toList());
        Map<String,Integer> recordStudentRegNum=new HashMap<>();
        BranchNumBlockVo branchNumBlockVo=new BranchNumBlockVo();
        Long areaTeamId=areaTeam.getAreaTeamId();
        String areaTeamName=areaTeam.getName();
        Long periodId=period.getPeriodId();
        String periodName=period.getPeriodName();
        Long gradeId=baseGrade.getGradeId();
        String gradeName=baseGrade.getGradeName();
        branchNumBlockVo.setAreaTeamId(areaTeamId);
        branchNumBlockVo.setAreaTeamName(areaTeamName);
        branchNumBlockVo.setPeriodId(periodId);
        branchNumBlockVo.setPeriodName(periodName);
        branchNumBlockVo.setGradeId(gradeId);
        branchNumBlockVo.setGradeName(gradeName);
        for (MergeStudentRegDetail mergeStudentRegDetail :periodGradeStudentRegList) {
            String key= mergeStudentRegDetail.getBusTeamId()+"_"+ mergeStudentRegDetail.getStudentId();
            if (!recordStudentRegNum.containsKey(key)){
                recordStudentRegNum.put(key,1);

            }else {
                recordStudentRegNum.put(key,recordStudentRegNum.get(key)+1);
            }
        }
        if (recordStudentRegNum.size()>0){
            Integer regBranch1=0;
            Integer regBranch2=0;
            Integer regBranch3=0;
            Integer regBranch4=0;
            Integer regBranch5=0;
            Integer regBranch6=0;
            Integer regBranch7=0;
            Integer regBranchOver=0;
            Integer studentNum=recordStudentRegNum.size();
            Double AvgNum=(double)(periodGradeStudentRegList.size()/(double)studentNum);
            branchNumBlockVo.setTotalPersonNum(studentNum);
            branchNumBlockVo.setTotalBranchNum(periodGradeStudentRegList.size());
            branchNumBlockVo.setAvgNum(new BigDecimal(AvgNum).setScale(2,   BigDecimal.ROUND_HALF_UP).doubleValue());
            for (Map.Entry<String,Integer> entry:recordStudentRegNum.entrySet()){
                Integer num=entry.getValue();
                switch (num){
                    case 1:
                        regBranch1++;
                        break;
                    case 2:
                        regBranch2++;
                        break;
                    case 3:
                        regBranch3++;
                        break;
                    case 4:
                        regBranch4++;
                        break;
                    case 5:
                        regBranch5++;
                        break;
                    case 6:
                        regBranch6++;
                        break;
                    case 7:
                        regBranch7++;
                        break;
                    default:
                        regBranchOver++;
                }
            }
            branchNumBlockVo.setPercentNum1(regBranch1);
            branchNumBlockVo.setPercent1(Utils.getPercent(regBranch1.toString(),studentNum.toString(),2));
            branchNumBlockVo.setPercentNum2(regBranch2);
            branchNumBlockVo.setPercent2(Utils.getPercent(regBranch2.toString(),studentNum.toString(),2));
            branchNumBlockVo.setPercentNum3(regBranch3);
            branchNumBlockVo.setPercent3(Utils.getPercent(regBranch3.toString(),studentNum.toString(),2));
            branchNumBlockVo.setPercentNum4(regBranch4);
            branchNumBlockVo.setPercent4(Utils.getPercent(regBranch4.toString(),studentNum.toString(),2));
            branchNumBlockVo.setPercentNum5(regBranch5);
            branchNumBlockVo.setPercent5(Utils.getPercent(regBranch5.toString(),studentNum.toString(),2));
            branchNumBlockVo.setPercentNum6(regBranch6);
            branchNumBlockVo.setPercent6(Utils.getPercent(regBranch6.toString(),studentNum.toString(),2));
            branchNumBlockVo.setPercentNum7(regBranch7);
            branchNumBlockVo.setPercent7(Utils.getPercent(regBranch7.toString(),studentNum.toString(),2));
            branchNumBlockVo.setPercentNumOver(regBranchOver);
            branchNumBlockVo.setPercentOver(Utils.getPercent(regBranchOver.toString(),studentNum.toString(),2));
        }
        return branchNumBlockVo;
    }

    @Override
    @Cacheable(value = "CacheOfBusTeamPeriodBranchNum",key = "#areaTeamId+'_'+#busTeamId+'_'+#periodId+'_'+#endDate")
    public BusTeamPeriodBranchNumVo findBusTeamPeriodBranchNum(long areaTeamId, long busTeamId, long periodId, String endDate) {
        BusTeamPeriodBranchNumVo busTeamPeriodBranchNumVo=new BusTeamPeriodBranchNumVo();
        busTeamPeriodBranchNumVo.setBusTeamId(busTeamId);
        busTeamPeriodBranchNumVo.setPeriodId(periodId);
        List<BranchNumBlockVo> branchNumBlockVoList=this.findBranchNumBlockVo(null,areaTeamId,Arrays.asList(busTeamId),Arrays.asList(periodId),null,null,null,TimeUtils.changeOneDateLastTime(Utils.parseDate(endDate,"yyyy-MM-dd")));
        if (Utils.checkListNotEmpty(branchNumBlockVoList)){
            for (BranchNumBlockVo branchNumBlockVo:branchNumBlockVoList){
                busTeamPeriodBranchNumVo.setTotalBranchNum(busTeamPeriodBranchNumVo.getTotalBranchNum()+branchNumBlockVo.getTotalBranchNum());
                busTeamPeriodBranchNumVo.setTotalPersonNum(busTeamPeriodBranchNumVo.getTotalPersonNum()+branchNumBlockVo.getTotalPersonNum());
            }
        }
        return busTeamPeriodBranchNumVo;
    }

    @Override
    public SXSSFWorkbook exportBlock(DataPermission dataPermission,Long areaTeamId, List<Long> busTeamIds, List<Long> periodIds, List<Long> gradeIds,List<Long> subjectIds, Date startDate, Date endDate) {
        BlockVo blockVo=this.findBlockVo(dataPermission,areaTeamId,busTeamIds,periodIds,gradeIds,subjectIds,startDate,endDate);

        return block2excel(blockVo);
    }
    public static SXSSFWorkbook block2excel(BlockVo blockVo) {
        SXSSFWorkbook excel = new SXSSFWorkbook();

        List<AdvanceBlockVo> advanceBlockVoList=blockVo.getAdvanceBlockVoList();
        List<StudentStateBlockVo> studentStateBlockVoList=blockVo.getStudentStateBlockVoList();
        List<BranchNumBlockVo> branchNumBlockVoList=blockVo.getBranchNumBlockVoList();


        excel=fillAdvanceExcel(excel,advanceBlockVoList,"预收");

        excel=fillStudentStateExcel(excel,studentStateBlockVoList, "生源");

        excel=fillBranchNumExcel(excel,branchNumBlockVoList,"科数");
        return excel;
    }

    private  static  SXSSFWorkbook  fillAdvanceExcel(SXSSFWorkbook excel,List<AdvanceBlockVo> advanceBlockVoList,String sheetName){
        SXSSFSheet sheet = excel.createSheet(sheetName);
        SXSSFRow firstRow = sheet.createRow(0);

        String[] titles = new String[]{"期数","区域","年级","预收金额","同期金额","目标金额","同期目标","预收进度","同期进度","预收同比","目标同比","科目目标","科目预收进度"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        BigDecimal totalAdvanceAmount=BigDecimal.ZERO;
        BigDecimal totalWithAdvanceAmount=BigDecimal.ZERO;
        BigDecimal totalTargetAmount=BigDecimal.ZERO;
        BigDecimal totalWithTargetAmount=BigDecimal.ZERO;
        BigDecimal totalSubjectTarget=BigDecimal.ZERO;

        for (AdvanceBlockVo advanceBlockVo:advanceBlockVoList){
            totalAdvanceAmount=totalAdvanceAmount.add(advanceBlockVo.getAdvanceAmount());
            totalWithAdvanceAmount=totalWithAdvanceAmount.add(advanceBlockVo.getWithAdvanceAmount());
            totalTargetAmount=totalTargetAmount.add(advanceBlockVo.getTargetAmount());
            totalWithTargetAmount=totalWithTargetAmount.add(advanceBlockVo.getWithTargetAmount());
            totalSubjectTarget=totalSubjectTarget.add(advanceBlockVo.getSubjectTarget());
            fillAdvanceExcelByVo(sheet,rowNum++,advanceBlockVo);
        }

        AdvanceBlockVo newAdvanceBlockVo=new AdvanceBlockVo();
        newAdvanceBlockVo.setPeriodName("合计");
        newAdvanceBlockVo.setAdvanceAmount(totalAdvanceAmount);
        newAdvanceBlockVo.setWithAdvanceAmount(totalWithAdvanceAmount);
        newAdvanceBlockVo.setTargetAmount(totalTargetAmount);
        newAdvanceBlockVo.setWithTargetAmount(totalWithTargetAmount);
        newAdvanceBlockVo.setSubjectTarget(totalSubjectTarget);
        newAdvanceBlockVo.setAdvanceProgress(Utils.getPercent(newAdvanceBlockVo.getAdvanceAmount().toString(),newAdvanceBlockVo.getTargetAmount().toString(),2));
        newAdvanceBlockVo.setWithProgress(Utils.getPercent(newAdvanceBlockVo.getWithAdvanceAmount().toString(),newAdvanceBlockVo.getWithTargetAmount().toString(),2));
        newAdvanceBlockVo.setAdvanceCompare(Utils.getPercent((newAdvanceBlockVo.getAdvanceAmount().subtract(newAdvanceBlockVo.getWithAdvanceAmount())).toString(),newAdvanceBlockVo.getWithAdvanceAmount().toString(),2));
        newAdvanceBlockVo.setTargetCompare(Utils.getPercent((newAdvanceBlockVo.getTargetAmount().subtract(newAdvanceBlockVo.getWithAdvanceAmount())).toString(),newAdvanceBlockVo.getWithAdvanceAmount().toString(),2));
        newAdvanceBlockVo.setSubjectTargetProgress(Utils.getPercent(newAdvanceBlockVo.getAdvanceAmount().toString(),newAdvanceBlockVo.getSubjectTarget().toString(),2));
        fillAdvanceExcelByVo(sheet,rowNum++,newAdvanceBlockVo);

        return excel;
    }
    private static void fillAdvanceExcelByVo(SXSSFSheet sheet,Integer rowNum,AdvanceBlockVo advanceBlockVo){
        int cellNum = 0;
        SXSSFRow row = sheet.createRow(rowNum++);

        SXSSFCell cell = row.createCell(cellNum++);
        cell.setCellValue(StringUtils.defaultString(advanceBlockVo.getPeriodName()));

        cell = row.createCell(cellNum++);
        cell.setCellValue(StringUtils.defaultString(advanceBlockVo.getAreaTeamName()));

        cell = row.createCell(cellNum++);
        cell.setCellValue(StringUtils.defaultString(advanceBlockVo.getGradeName()));

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(advanceBlockVo.getAdvanceAmount(),"0.00")));

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(advanceBlockVo.getWithAdvanceAmount(),"0.00")));

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(advanceBlockVo.getTargetAmount(),"0.00")));

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(advanceBlockVo.getWithTargetAmount(),"0.00")));

        cell = row.createCell(cellNum++);
        cell.setCellValue(advanceBlockVo.getAdvanceProgress());

        cell = row.createCell(cellNum++);
        cell.setCellValue(advanceBlockVo.getWithProgress());

        cell = row.createCell(cellNum++);
        cell.setCellValue(advanceBlockVo.getAdvanceCompare());

        cell = row.createCell(cellNum++);
        cell.setCellValue(advanceBlockVo.getTargetCompare());


        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(advanceBlockVo.getSubjectTarget(),"0.00")));

        cell = row.createCell(cellNum++);
        cell.setCellValue(advanceBlockVo.getSubjectTargetProgress());


    }


    private  static  SXSSFWorkbook  fillStudentStateExcel(SXSSFWorkbook excel,List<StudentStateBlockVo> studentStateBlockVoList,String sheetName){
        SXSSFSheet sheet = excel.createSheet(sheetName);
        SXSSFRow firstRow = sheet.createRow(0);

        String[] titles = new String[]{"期数","区域","年级","报读人数","同期报读","新生人数","同期新生","老生人数","同期老生","续读人数","同期续读"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;

        Integer regStudentNum=0;
        Integer withStudentNum=0;
        Integer newStudentNum=0;
        Integer withNewStudentNum=0;
        Integer oldStudentNum=0;
        Integer withOldStudentNum=0;
        Integer seqStepStudentNum=0;
        Integer withSeqStepStudentNum=0;
        for (StudentStateBlockVo studentStateBlockVo:studentStateBlockVoList){
            regStudentNum=regStudentNum+(studentStateBlockVo.getRegStudentNum()==null?0:studentStateBlockVo.getRegStudentNum());
            withStudentNum=withStudentNum+(studentStateBlockVo.getWithStudentNum()==null?0:studentStateBlockVo.getWithStudentNum());
            newStudentNum=newStudentNum+(studentStateBlockVo.getNewStudentNum()==null?0:studentStateBlockVo.getNewStudentNum());
            withNewStudentNum=withNewStudentNum+(studentStateBlockVo.getWithNewStudentNum()==null?0:studentStateBlockVo.getWithNewStudentNum());
            oldStudentNum=oldStudentNum+(studentStateBlockVo.getOldStudentNum()==null?0:studentStateBlockVo.getOldStudentNum());
            withOldStudentNum=withOldStudentNum+(studentStateBlockVo.getWithOldStudentNum()==null?0:studentStateBlockVo.getWithOldStudentNum());
            seqStepStudentNum=seqStepStudentNum+(studentStateBlockVo.getSeqStepStudentNum()==null?0:studentStateBlockVo.getSeqStepStudentNum());
            withSeqStepStudentNum=withSeqStepStudentNum+(studentStateBlockVo.getWithSeqStepStudentNum()==null?0:studentStateBlockVo.getWithSeqStepStudentNum());
            fillStudentStateExcel(sheet,rowNum++,studentStateBlockVo);
        }
        StudentStateBlockVo studentStateBlockVo=new StudentStateBlockVo();
        studentStateBlockVo.setPeriodName("总计");
        studentStateBlockVo.setAreaTeamName("");
        studentStateBlockVo.setGradeName("");
        studentStateBlockVo.setRegStudentNum(regStudentNum);
        studentStateBlockVo.setWithStudentNum(withStudentNum);
        studentStateBlockVo.setNewStudentNum(newStudentNum);
        studentStateBlockVo.setWithNewStudentNum(withNewStudentNum);
        studentStateBlockVo.setOldStudentNum(oldStudentNum);
        studentStateBlockVo.setWithOldStudentNum(withOldStudentNum);
        studentStateBlockVo.setSeqStepStudentNum(seqStepStudentNum);
        studentStateBlockVo.setWithSeqStepStudentNum(withSeqStepStudentNum);
        fillStudentStateExcel(sheet,rowNum++,studentStateBlockVo);
        return excel;
    }

    private static void fillStudentStateExcel(SXSSFSheet sheet,Integer rowNum,StudentStateBlockVo studentStateBlockVo){
        int cellNum = 0;
        SXSSFRow row = sheet.createRow(rowNum++);

        SXSSFCell cell = row.createCell(cellNum++);
        cell.setCellValue(studentStateBlockVo.getPeriodName());

        cell = row.createCell(cellNum++);
        cell.setCellValue(studentStateBlockVo.getAreaTeamName());

        cell = row.createCell(cellNum++);
        cell.setCellValue(studentStateBlockVo.getGradeName());

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(studentStateBlockVo.getRegStudentNum());

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(studentStateBlockVo.getWithStudentNum());

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(studentStateBlockVo.getNewStudentNum());

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(studentStateBlockVo.getWithNewStudentNum());

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(studentStateBlockVo.getOldStudentNum());

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(studentStateBlockVo.getWithOldStudentNum());

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(studentStateBlockVo.getSeqStepStudentNum());

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(studentStateBlockVo.getWithSeqStepStudentNum());
    }


    private  static  SXSSFWorkbook  fillBranchNumExcel(SXSSFWorkbook excel,List<BranchNumBlockVo> branchNumBlockVoList,String sheetName){
        SXSSFSheet sheet = excel.createSheet(sheetName);
        SXSSFRow firstRow = sheet.createRow(0);

        String[] titles = new String[]{"期数","区域","年级","人数","科数","人均科数","报读一科（占比）","报读两科（占比）","报读三科（占比）","报读四科（占比）","报读五科（占比）","报读六科（占比）","报读七科（占比）","报读七科以上（占比）"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }

        int rowNum=1;
        BranchNumBlockVo totalBranchNumBlockVo=new BranchNumBlockVo();
        for (BranchNumBlockVo branchNumBlockVo:branchNumBlockVoList){
            totalBranchNumBlockVo.setTotalPersonNum(totalBranchNumBlockVo.getTotalPersonNum()+branchNumBlockVo.getTotalPersonNum());
            totalBranchNumBlockVo.setTotalBranchNum(totalBranchNumBlockVo.getTotalBranchNum()+branchNumBlockVo.getTotalBranchNum());
            totalBranchNumBlockVo.setPercentNum1(totalBranchNumBlockVo.getPercentNum1()+branchNumBlockVo.getPercentNum1());
            totalBranchNumBlockVo.setPercentNum2(totalBranchNumBlockVo.getPercentNum2()+branchNumBlockVo.getPercentNum2());
            totalBranchNumBlockVo.setPercentNum3(totalBranchNumBlockVo.getPercentNum3()+branchNumBlockVo.getPercentNum3());
            totalBranchNumBlockVo.setPercentNum4(totalBranchNumBlockVo.getPercentNum4()+branchNumBlockVo.getPercentNum4());
            totalBranchNumBlockVo.setPercentNum5(totalBranchNumBlockVo.getPercentNum5()+branchNumBlockVo.getPercentNum5());
            totalBranchNumBlockVo.setPercentNum6(totalBranchNumBlockVo.getPercentNum6()+branchNumBlockVo.getPercentNum6());
            totalBranchNumBlockVo.setPercentNum7(totalBranchNumBlockVo.getPercentNum7()+branchNumBlockVo.getPercentNum7());
            totalBranchNumBlockVo.setPercentNumOver(totalBranchNumBlockVo.getPercentNumOver()+branchNumBlockVo.getPercentNumOver());

            fillBranchNumExcelByVo(sheet,rowNum++,branchNumBlockVo);
        }
        totalBranchNumBlockVo.setPeriodName("总计");
        totalBranchNumBlockVo.setAreaTeamName("");
        totalBranchNumBlockVo.setGradeName("");
        if (totalBranchNumBlockVo.getTotalPersonNum()!=null && totalBranchNumBlockVo.getTotalPersonNum()!=0 && totalBranchNumBlockVo.getTotalBranchNum()!=null){
            totalBranchNumBlockVo.setAvgNum(new BigDecimal(totalBranchNumBlockVo.getTotalBranchNum()/(double)totalBranchNumBlockVo.getTotalPersonNum()).setScale(2,   BigDecimal.ROUND_HALF_UP).doubleValue());
        }
        totalBranchNumBlockVo.setPercent1(Utils.getPercent(totalBranchNumBlockVo.getPercentNum1().toString(),totalBranchNumBlockVo.getTotalPersonNum().toString(),2));
        totalBranchNumBlockVo.setPercent2(Utils.getPercent(totalBranchNumBlockVo.getPercentNum2().toString(),totalBranchNumBlockVo.getTotalPersonNum().toString(),2));
        totalBranchNumBlockVo.setPercent3(Utils.getPercent(totalBranchNumBlockVo.getPercentNum3().toString(),totalBranchNumBlockVo.getTotalPersonNum().toString(),2));
        totalBranchNumBlockVo.setPercent4(Utils.getPercent(totalBranchNumBlockVo.getPercentNum4().toString(),totalBranchNumBlockVo.getTotalPersonNum().toString(),2));
        totalBranchNumBlockVo.setPercent5(Utils.getPercent(totalBranchNumBlockVo.getPercentNum5().toString(),totalBranchNumBlockVo.getTotalPersonNum().toString(),2));
        totalBranchNumBlockVo.setPercent6(Utils.getPercent(totalBranchNumBlockVo.getPercentNum6().toString(),totalBranchNumBlockVo.getTotalPersonNum().toString(),2));
        totalBranchNumBlockVo.setPercent7(Utils.getPercent(totalBranchNumBlockVo.getPercentNum7().toString(),totalBranchNumBlockVo.getTotalPersonNum().toString(),2));
        totalBranchNumBlockVo.setPercentOver(Utils.getPercent(totalBranchNumBlockVo.getPercentNumOver().toString(),totalBranchNumBlockVo.getTotalPersonNum().toString(),2));

        fillBranchNumExcelByVo(sheet,rowNum++,totalBranchNumBlockVo);


        return excel;
    }

    private static void fillBranchNumExcelByVo(SXSSFSheet sheet, Integer rowNum,BranchNumBlockVo branchNumBlockVo){
        int cellNum = 0;
        SXSSFRow row = sheet.createRow(rowNum++);

        SXSSFCell cell = row.createCell(cellNum++);
        cell.setCellValue(branchNumBlockVo.getPeriodName());

        cell = row.createCell(cellNum++);
        cell.setCellValue(branchNumBlockVo.getAreaTeamName());

        cell = row.createCell(cellNum++);
        cell.setCellValue(branchNumBlockVo.getGradeName());

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(branchNumBlockVo.getTotalPersonNum());

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(branchNumBlockVo.getTotalBranchNum());

        cell = row.createCell(cellNum++);
        cell.setCellType(CellType.NUMERIC);
        cell.setCellValue(branchNumBlockVo.getAvgNum());

        cell = row.createCell(cellNum++);
        cell.setCellValue(branchNumBlockVo.getPercentNum1()+"("+branchNumBlockVo.getPercent1()+")");

        cell = row.createCell(cellNum++);
        cell.setCellValue(branchNumBlockVo.getPercentNum2()+"("+branchNumBlockVo.getPercent2()+")");

        cell = row.createCell(cellNum++);
        cell.setCellValue(branchNumBlockVo.getPercentNum3()+"("+branchNumBlockVo.getPercent3()+")");

        cell = row.createCell(cellNum++);
        cell.setCellValue(branchNumBlockVo.getPercentNum4()+"("+branchNumBlockVo.getPercent4()+")");

        cell = row.createCell(cellNum++);
        cell.setCellValue(branchNumBlockVo.getPercentNum5()+"("+branchNumBlockVo.getPercent5()+")");

        cell = row.createCell(cellNum++);
        cell.setCellValue(branchNumBlockVo.getPercentNum6()+"("+branchNumBlockVo.getPercent6()+")");

        cell = row.createCell(cellNum++);
        cell.setCellValue(branchNumBlockVo.getPercentNum7()+"("+branchNumBlockVo.getPercent7()+")");

        cell = row.createCell(cellNum++);
        cell.setCellValue(branchNumBlockVo.getPercentNumOver()+"("+branchNumBlockVo.getPercentOver()+")");
    }


    private static SXSSFWorkbook businessSituation2excel(List<BusinessSituationVo> businessSituationVoList,SXSSFWorkbook excel){

        SXSSFSheet sheet = excel.createSheet("营业概况");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"期数","业务组","年级","目标金额","总计金额","实收金额","优惠金额","金额完成率","优惠率","新生人数","新生科数","新生金额","老生人数","老生科数","老生金额","续读人数","续读科数","续读金额"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        for (BusinessSituationVo businessSituationVo:businessSituationVoList){
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(businessSituationVo.getPeriodName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(businessSituationVo.getBusTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(businessSituationVo.getGradeName());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(businessSituationVo.getTargetAmount(),"0.00")));

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(businessSituationVo.getTotalAmount(),"0.00")));

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(businessSituationVo.getRealAmount(),"0.00")));

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(businessSituationVo.getDiscountAmount(),"0.00")));

            cell = row.createCell(cellNum++);
            cell.setCellValue(businessSituationVo.getAmountRate());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(businessSituationVo.getRealAmount().toString(),businessSituationVo.getRealAmount().add(businessSituationVo.getDiscountAmount()).toString(),2));


            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(businessSituationVo.getNewStudentPersonNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(businessSituationVo.getNewStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(businessSituationVo.getNewStudentAmount(),"0.00")));

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(businessSituationVo.getOldStudentPersonNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(businessSituationVo.getOldStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(businessSituationVo.getOldStudentAmount(),"0.00")));

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(businessSituationVo.getSeqStepPersonNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(businessSituationVo.getSeqStepNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(businessSituationVo.getSeqStepAmount(),"0.00")));

        }
        return excel;
    }

    private static SXSSFWorkbook periodGradeSubjectSituation2excel(List<PeriodGradeSubjectSituationVo> periodGradeSubjectSituationVoList,SXSSFWorkbook excel){

        SXSSFSheet sheet = excel.createSheet("区域年级科目概况");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"区域","期数","年级","科目","目标金额","总计金额","实收金额","优惠金额","金额完成率","新生人数","新生科数","新生金额","老生人数","老生科数","老生金额","续读人数","续读科数","续读金额"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        for (PeriodGradeSubjectSituationVo periodGradeSubjectSituationVo:periodGradeSubjectSituationVoList){
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(periodGradeSubjectSituationVo.getAreaTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodGradeSubjectSituationVo.getPeriodName());


            cell = row.createCell(cellNum++);
            cell.setCellValue(periodGradeSubjectSituationVo.getGradeName());


            cell = row.createCell(cellNum++);
            cell.setCellValue(periodGradeSubjectSituationVo.getSubjectName());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(periodGradeSubjectSituationVo.getTargetAmount(),"0.00")));

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(periodGradeSubjectSituationVo.getTotalAmount(),"0.00")));

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(periodGradeSubjectSituationVo.getRealAmount(),"0.00")));

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(periodGradeSubjectSituationVo.getDiscountAmount(),"0.00")));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodGradeSubjectSituationVo.getAmountRate());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(periodGradeSubjectSituationVo.getNewStudentPersonNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(periodGradeSubjectSituationVo.getNewStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(periodGradeSubjectSituationVo.getNewStudentAmount(),"0.00")));

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(periodGradeSubjectSituationVo.getOldStudentPersonNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(periodGradeSubjectSituationVo.getOldStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(periodGradeSubjectSituationVo.getOldStudentAmount(),"0.00")));

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(periodGradeSubjectSituationVo.getSeqStepPersonNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(periodGradeSubjectSituationVo.getSeqStepNum());

            cell = row.createCell(cellNum++);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Double.parseDouble(BigDecimals.formatBigDecimal(periodGradeSubjectSituationVo.getSeqStepAmount(),"0.00")));

        }
        return excel;
    }


    @Override
    public AmountBranchPerson findAmountBranchPerson(List<Long> busTeamIds,Long areaTeamId, List<Long> periodIds, List<Long> gradeIds, Date startDate, Date endDate) {
        if (startDate==null || endDate==null){
            throw  new BusException("开始结束时间必选");
        }
        AmountBranchPerson amountBranchPerson=new AmountBranchPerson();
        CourseClassQueryVo courseClassQueryVo=new CourseClassQueryVo();
        courseClassQueryVo.setAreaTeamId(areaTeamId);
        List<CourseClass> courseClassList=courseClassService.findCourseClassByQueryForList(courseClassQueryVo,null,busTeamIds,periodIds,gradeIds,"classId","periodId","gradeId","subjectId");
        Map<Long,CourseClass> courseClassMap=BeanUtils.toMap(courseClassList,"classId");

        List<BusTeam> busTeamList=busTeamService.findByIds(busTeamIds);

        StudentRefundQueryVo studentRefundQueryVo=new StudentRefundQueryVo();
        studentRefundQueryVo.setAreaTeamId(areaTeamId);
        studentRefundQueryVo.setStartAuditTime(startDate);
        studentRefundQueryVo.setEndAuditTime(endDate);
        studentRefundQueryVo.setStatus(1);
        studentRefundQueryVo.setGradeIds(gradeIds);
        List<StudentRefund> studentRefundList=studentRefundService.findListByQueryVo(studentRefundQueryVo,busTeamIds,periodIds,1);

        List<Long> classIds=BeanUtils.toList(studentRefundList,"classId");
        classIds=Utils.removeDuplicate(classIds);
        List<Long> studentIds=BeanUtils.toList(studentRefundList,"studentId");
        studentIds=Utils.removeDuplicate(studentIds);
        List<MergeStudentRegDetail> refundRegDetails = mergeStudentRegDetailService.findByStudentIdsClassIds(studentIds,classIds, studentRegDetailColumns);
        Map<String, List<StudentRefund>> refundRegMap = new HashMap<>();//BeanUtils.toGroup(studentRefundList, "studentRegId");

        for (StudentRefund studentRefund:studentRefundList){
            String key=studentRefund.getStudentId()+"_"+studentRefund.getClassId();
            List<StudentRefund> studentRefunds=refundRegMap.get(key);
            if (studentRefunds==null){
                studentRefunds=new ArrayList<>();
                refundRegMap.put(key,studentRefunds);
            }
            studentRefunds.add(studentRefund);

        }

        Map<Long,List<MergeStudentRegDetail>> refundRegDetailMap=BeanUtils.toGroup(refundRegDetails,"busTeamId");

        PeriodQueryRegVo periodQueryRegVo=new PeriodQueryRegVo();
        periodQueryRegVo.setAreaTeamId(areaTeamId);
        //periodQueryRegVo.setRegStatus(0);
        periodQueryRegVo.setStartDate(startDate);
        periodQueryRegVo.setEndDate(endDate);
        List<MergeStudentRegDetail> mergeStudentRegDetailList =mergeStudentRegDetailService.findListStudentRegByQuery(Arrays.asList(0,3),periodQueryRegVo,gradeIds,periodIds,busTeamIds,studentRegDetailColumns);

        Map<Long,List<MergeStudentRegDetail>> studentRegDetailMap=BeanUtils.toGroup(mergeStudentRegDetailList,"busTeamId");


        List<AmountDataVo> amountList = new ArrayList<>(busTeamIds.size());
        List<BranchDataVo> branchList = new ArrayList<>(busTeamIds.size());
        List<PersonDataVo> personList = new ArrayList<>(busTeamIds.size());
        for (BusTeam busTeam:busTeamList){
            Long busTeamId=busTeam.getBusTeamId();
            String busTeamName=busTeam.getName();
            List<MergeStudentRegDetail> oneBusTeamRegDetailList=studentRegDetailMap.get(busTeamId);
            List<MergeStudentRegDetail> oneBusTeamRefundList=refundRegDetailMap.get(busTeamId);
            Map<String,List<Long>> checkPersonRecord =new HashMap<>(); //key= periodId_studentId 记录这段时间学生真实的在读科数
            Map<String,List<Long>> checkDatePersonRecord =new HashMap<>();//key=date_periodId_studentId
            AmountDataVo amountVo=new AmountDataVo();
            BranchDataVo branchVo=new BranchDataVo();
            PersonDataVo personVo=new PersonDataVo();
            amountVo.setBusTeamId(busTeamId);
            amountVo.setBusTeamName(busTeamName);
            branchVo.setBusTeamId(busTeamId);
            branchVo.setBusTeamName(busTeamName);
            personVo.setBusTeamId(busTeamId);
            personVo.setBusTeamName(busTeamName);
            Map<String,AmountDetailVo> amountDetailMap=new TreeMap<>();
            Map<String,BranchDetailVo> branchDetailMap=new TreeMap<>();
            Map<String,PersonDetailVo> personDetailMap=new TreeMap<>();

            Date begin=startDate;
            while (begin.getTime()<=endDate.getTime()){
                String dateKey=Utils.formatDate(begin,"yyyy-MM-dd");
                AmountDetailVo amountDetailVo=new AmountDetailVo();
                amountDetailVo.setDateStr(dateKey);
                amountDetailVo.setBusTeamId(busTeamId);
                amountDetailVo.setBusTeamName(busTeamName);

                BranchDetailVo branchDetailVo=new BranchDetailVo();
                branchDetailVo.setDateStr(dateKey);
                branchDetailVo.setBusTeamId(busTeamId);
                branchDetailVo.setBusTeamName(busTeamName);

                PersonDetailVo personDetailVo=new PersonDetailVo();
                personDetailVo.setDateStr(dateKey);
                personDetailVo.setBusTeamId(busTeamId);
                personDetailVo.setBusTeamName(busTeamName);
                begin=TimeUtils.changeDateByNum(begin,1);

                amountDetailMap.put(dateKey,amountDetailVo);
                branchDetailMap.put(dateKey,branchDetailVo);
                personDetailMap.put(dateKey,personDetailVo);
            }

            if (oneBusTeamRegDetailList!=null){
                for (MergeStudentRegDetail mergeStudentRegDetail :oneBusTeamRegDetailList){
                    if(mergeStudentRegDetail.getStudentState()==null){
                        continue;
                    }
                    String recordKey= mergeStudentRegDetail.getPeriodId()+"_"+ mergeStudentRegDetail.getStudentId()+"_"+ mergeStudentRegDetail.getStudentState()+"_"+ mergeStudentRegDetail.getGradeId();
                    String dateKey=Utils.formatDate(mergeStudentRegDetail.getCreateTime(),"yyyy-MM-dd");
                    String dateRecordKey=dateKey+"_"+recordKey+"_"+ mergeStudentRegDetail.getStudentState();
                    AmountDetailVo amountDetailVo =amountDetailMap.get(dateKey)==null?new AmountDetailVo():amountDetailMap.get(dateKey);
                    BranchDetailVo branchDetailVo =branchDetailMap.get(dateKey)==null?new BranchDetailVo():branchDetailMap.get(dateKey);
                    PersonDetailVo personDetailVo =personDetailMap.get(dateKey)==null?new PersonDetailVo():personDetailMap.get(dateKey);


                    BigDecimal realAmount= mergeStudentRegDetail.getPayAmount();//第一次缴费的金额，后面再根据studentrefund的数据减去
                    amountVo.setTotalNum(amountVo.getTotalNum()+ mergeStudentRegDetail.getPayAmount().doubleValue());
                    branchVo.setTotalNum(branchVo.getTotalNum()+1);

                    if (!checkPersonRecord.containsKey(recordKey)){
                        personVo.setTotalNum(personVo.getTotalNum()+1);
                    }

                    if (!checkDatePersonRecord.containsKey(dateRecordKey)){
                        personDetailVo.setTotalNum(personDetailVo.getTotalNum()+1);
                    }

                    amountDetailVo.setTotalNum(amountDetailVo.getTotalNum()+realAmount.doubleValue());
                    branchDetailVo.setTotalNum(branchDetailVo.getTotalNum()+1);
                    if (mergeStudentRegDetail.getStudentState()==0){
                        amountVo.setNewStudentNum(amountVo.getNewStudentNum()+realAmount.doubleValue());
                        amountDetailVo.setNewStudentNum(amountDetailVo.getNewStudentNum()+realAmount.doubleValue());

                        branchVo.setNewStudentNum(branchVo.getNewStudentNum()+1);
                        branchDetailVo.setNewStudentNum(branchDetailVo.getNewStudentNum()+1);

                        if (!checkPersonRecord.containsKey(recordKey)){
                            personVo.setNewStudentNum(personVo.getNewStudentNum()+1);
                        }
                        if (!checkDatePersonRecord.containsKey(dateRecordKey)){
                            personDetailVo.setNewStudentNum(personDetailVo.getNewStudentNum()+1);
                        }

                    }else if(mergeStudentRegDetail.getStudentState()==1){
                        amountVo.setOldStudentNum(amountVo.getOldStudentNum()+realAmount.doubleValue());
                        amountDetailVo.setOldStudentNum(amountDetailVo.getOldStudentNum()+realAmount.doubleValue());

                        branchVo.setOldStudentNum(branchVo.getOldStudentNum()+1);
                        branchDetailVo.setOldStudentNum(branchDetailVo.getOldStudentNum()+1);

                        if (!checkPersonRecord.containsKey(recordKey)){
                            personVo.setOldStudentNum(personVo.getOldStudentNum()+1);
                        }
                        if (!checkDatePersonRecord.containsKey(dateRecordKey)){
                            personDetailVo.setOldStudentNum(personDetailVo.getOldStudentNum()+1);
                        }
                    }else if (mergeStudentRegDetail.getStudentState()==2){
                        amountVo.setSeqStepStudentNum(amountVo.getSeqStepStudentNum()+realAmount.doubleValue());
                        amountDetailVo.setSeqStepStudentNum(amountDetailVo.getSeqStepStudentNum()+realAmount.doubleValue());

                        branchVo.setSeqStepStudentNum(branchVo.getSeqStepStudentNum()+1);
                        branchDetailVo.setSeqStepStudentNum(branchDetailVo.getSeqStepStudentNum()+1);
                        if (!checkPersonRecord.containsKey(recordKey)){
                            personVo.setSeqStepStudentNum(personVo.getSeqStepStudentNum()+1);
                        }
                        if (!checkDatePersonRecord.containsKey(dateRecordKey)){
                            personDetailVo.setSeqStepStudentNum(personDetailVo.getSeqStepStudentNum()+1);
                        }
                    }
                    List<Long> studentRegIdList=checkPersonRecord.get(recordKey);
                    if (studentRegIdList==null){
                        studentRegIdList=new ArrayList<>();
                    }
                    studentRegIdList.add(mergeStudentRegDetail.getRegId());
                    checkPersonRecord.put(recordKey,studentRegIdList);

                    List<Long> studentRegOneDayIdList=checkDatePersonRecord.get(dateRecordKey);
                    if(studentRegOneDayIdList==null){
                        studentRegOneDayIdList=new ArrayList<>();
                    }
                    studentRegOneDayIdList.add(mergeStudentRegDetail.getRegId());
                    checkDatePersonRecord.put(dateRecordKey,studentRegOneDayIdList);

                    amountDetailMap.put(dateKey,amountDetailVo);
                    branchDetailMap.put(dateKey,branchDetailVo);
                    personDetailMap.put(dateKey,personDetailVo);
                }
            }

            /*根据学生studentrefund 的记录，对上面的数据进行处理，金额减去，科数减去，人数减去，
            *
            * */
            if (oneBusTeamRefundList!=null){
                Map<String,Integer> checkRefundPersonRecord =new HashMap<>(); //key= periodId_studentId
                Map<String,Integer> checkRefundDatePersonRecord =new HashMap<>();//key= date_periodId_studentId,
                for (MergeStudentRegDetail mergeStudentRegDetail :oneBusTeamRefundList){
                    List<StudentRefund> oneStudentRefundList=refundRegMap.get(mergeStudentRegDetail.getStudentId()+"_"+mergeStudentRegDetail.getClassId());
                    if (oneStudentRefundList==null){
                        continue;
                    }
                    CourseClass courseClass=courseClassMap.get(mergeStudentRegDetail.getClassId());
                    if (mergeStudentRegDetail.getStudentState()==null || courseClass==null || !gradeIds.contains(courseClass.getGradeId())){
                        continue;
                    }
                    BigDecimal totalRefundAmount=BigDecimal.ZERO;
                    for (StudentRefund studentRefund:oneStudentRefundList){

                        BigDecimal refundAmount=studentRefund.getAmount();
                        totalRefundAmount=totalRefundAmount.add(refundAmount);
                        Integer branchNum=0;
                        BigDecimal studentRegRefund= mergeStudentRegDetail.getRefundAmount()==null?BigDecimal.ZERO: mergeStudentRegDetail.getRefundAmount();
                        if (totalRefundAmount.equals(studentRegRefund) && mergeStudentRegDetail.getRegStatus()!=0){
                            branchNum=1;
                        }

                        String recordKey=studentRefund.getPeriodId()+"_"+studentRefund.getStudentId()+"_"+ mergeStudentRegDetail.getStudentState()+"_"+ mergeStudentRegDetail.getGradeId();
                        String dateKey=Utils.formatDate(studentRefund.getAuditTime(),"yyyy-MM-dd");
                        String dateRecordKey=dateKey+"_"+recordKey+"_"+ mergeStudentRegDetail.getStudentState();
                        amountVo.setTotalNum(amountVo.getTotalNum()-refundAmount.doubleValue());
                        branchVo.setTotalNum(branchVo.getTotalNum()-branchNum);

                        AmountDetailVo amountDetailVo =amountDetailMap.get(dateKey)==null?new AmountDetailVo():amountDetailMap.get(dateKey);
                        BranchDetailVo branchDetailVo =branchDetailMap.get(dateKey)==null?new BranchDetailVo():branchDetailMap.get(dateKey);
                        PersonDetailVo personDetailVo =personDetailMap.get(dateKey)==null?new PersonDetailVo():personDetailMap.get(dateKey);

                        amountDetailVo.setDateStr(dateKey);
                        amountDetailVo.setBusTeamId(busTeamId);
                        amountDetailVo.setBusTeamName(busTeamName);

                        branchDetailVo.setDateStr(dateKey);
                        branchDetailVo.setBusTeamId(busTeamId);
                        branchDetailVo.setBusTeamName(busTeamName);

                        personDetailVo.setDateStr(dateKey);
                        personDetailVo.setBusTeamId(busTeamId);
                        personDetailVo.setBusTeamName(busTeamName);

                        amountDetailVo.setTotalNum(amountDetailVo.getTotalNum()-refundAmount.doubleValue());
                        branchDetailVo.setTotalNum(branchDetailVo.getTotalNum()-branchNum);

                        if (mergeStudentRegDetail.getStudentState()!=null && mergeStudentRegDetail.getStudentState()==0){
                            amountVo.setNewStudentNum(amountVo.getNewStudentNum()-refundAmount.doubleValue());
                            amountDetailVo.setNewStudentNum(amountDetailVo.getNewStudentNum()-refundAmount.doubleValue());

                            branchVo.setNewStudentNum(branchVo.getNewStudentNum()-branchNum);
                            branchDetailVo.setNewStudentNum(branchDetailVo.getNewStudentNum()-branchNum);

                        }else if(mergeStudentRegDetail.getStudentState()!=null && mergeStudentRegDetail.getStudentState()==1){
                            amountVo.setOldStudentNum(amountVo.getOldStudentNum()-refundAmount.doubleValue());
                            amountDetailVo.setOldStudentNum(amountDetailVo.getOldStudentNum()-refundAmount.doubleValue());

                            branchVo.setOldStudentNum(branchVo.getOldStudentNum()-branchNum);
                            branchDetailVo.setOldStudentNum(branchDetailVo.getOldStudentNum()-branchNum);

                        }else if (mergeStudentRegDetail.getStudentState()!=null && mergeStudentRegDetail.getStudentState()==2){
                            amountVo.setSeqStepStudentNum(amountVo.getSeqStepStudentNum()-studentRefund.getAmount().doubleValue());
                            amountDetailVo.setSeqStepStudentNum(amountDetailVo.getSeqStepStudentNum()-refundAmount.doubleValue());

                            branchVo.setSeqStepStudentNum(branchVo.getSeqStepStudentNum()-branchNum);
                            branchDetailVo.setSeqStepStudentNum(branchDetailVo.getSeqStepStudentNum()-branchNum);

                        }

                        if (branchNum==1){
                            /*这段时间学生是否在读，并且未被减去*/
                            List<Long> checkIdList=checkPersonRecord.get(recordKey);
                            if (checkIdList!=null){
                                checkIdList.remove(mergeStudentRegDetail.getRegId());
                            }
                            if (!checkRefundPersonRecord.containsKey(recordKey) && (checkIdList==null || checkIdList.size()==0)){
                                personVo.setTotalNum(personVo.getTotalNum()-1);
                                if (mergeStudentRegDetail.getStudentState()!=null && mergeStudentRegDetail.getStudentState()==0){
                                    personVo.setNewStudentNum(personVo.getNewStudentNum()-1);
                                }else if (mergeStudentRegDetail.getStudentState()!=null && mergeStudentRegDetail.getStudentState()==1){
                                    personVo.setOldStudentNum(personVo.getOldStudentNum()-1);
                                }else if (mergeStudentRegDetail.getStudentState()!=null && mergeStudentRegDetail.getStudentState()==2){
                                    personVo.setSeqStepStudentNum(personVo.getSeqStepStudentNum()-1);
                                }
                                checkRefundPersonRecord.put(recordKey,1);
                            }
                             /*这一天学生是否在读，并且未被减去*/
                            List<Long>  datePersonReg=checkDatePersonRecord.get(dateRecordKey);
                            if (datePersonReg!=null){
                                datePersonReg.remove(mergeStudentRegDetail.getRegId());
                            }
                            if (!checkRefundDatePersonRecord.containsKey(dateRecordKey) && (datePersonReg==null || datePersonReg.size()<=0) ){
                                personDetailVo.setTotalNum(personDetailVo.getTotalNum() - 1);
                                if (mergeStudentRegDetail.getStudentState() != null && mergeStudentRegDetail.getStudentState() == 0) {
                                    personDetailVo.setNewStudentNum(personDetailVo.getNewStudentNum() - 1);
                                } else if (mergeStudentRegDetail.getStudentState() != null && mergeStudentRegDetail.getStudentState() == 1) {
                                    personDetailVo.setOldStudentNum(personDetailVo.getOldStudentNum() - 1);
                                } else if (mergeStudentRegDetail.getStudentState() != null && mergeStudentRegDetail.getStudentState() == 2) {
                                    personDetailVo.setSeqStepStudentNum(personDetailVo.getSeqStepStudentNum() - 1);
                                }
                                checkRefundDatePersonRecord.put(dateRecordKey,1);
                            }
                        }
                        amountDetailMap.put(dateKey,amountDetailVo);
                        branchDetailMap.put(dateKey,branchDetailVo);
                        personDetailMap.put(dateKey,personDetailVo);
                    }
                }
            }
            Collection<AmountDetailVo> amountValues = amountDetailMap.values();
            List<AmountDetailVo> amountDetailVoList=new ArrayList<>(amountValues);
            amountVo.setAmountBranchPersonDetailVoList(amountDetailVoList);

            Collection<BranchDetailVo> branchValues =branchDetailMap.values();
            List<BranchDetailVo> branchDetailVoList=new ArrayList<>(branchValues);
            branchVo.setAmountBranchPersonDetailVoList(branchDetailVoList);

            Collection<PersonDetailVo> personValues = personDetailMap.values();
            List<PersonDetailVo> personDetailVoList=new ArrayList<>(personValues);
            personVo.setAmountBranchPersonDetailVoList(personDetailVoList);

            amountList.add(amountVo);
            branchList.add(branchVo);
            personList.add(personVo);
        }

        amountBranchPerson.setAmountList(amountList);
        amountBranchPerson.setBranchList(branchList);
        amountBranchPerson.setPersonList(personList);
        return amountBranchPerson;
    }


    @Override
    public SXSSFWorkbook exportAmountBranchPerson(List<Long> busTeamIds, Long areaTeamId, List<Long> periodIds, List<Long> gradeIds, Date startDate, Date endDate) {
        AmountBranchPerson amountBranchPerson=this.findAmountBranchPerson(busTeamIds,areaTeamId,periodIds,gradeIds,startDate,endDate);
        SXSSFWorkbook excel=amountBranchPerson2excel(amountBranchPerson);
        return excel;
    }


    @Override
    public PeriodRegVo findPeriodAndWithPeriod(Long areaTeamId, List<Long> busTeamIds, List<Long> periodIds, List<Long> gradeIds,List<Long> subjectIds, Date startDate, Date endDate,List<Integer> regStatuses, int needWithPeriod,int needFindRefund) {
        PeriodRegVo periodRegVo=new PeriodRegVo();

        if (Utils.checkListEmpty(gradeIds)){
            periodRegVo.setBaseGradeList(baseGradeService.findAllOrderGrade());
        }else {
            periodRegVo.setBaseGradeList(baseGradeService.findDealOtherPosition(gradeIds));
        }
        gradeIds=BeanUtils.toList(periodRegVo.getBaseGradeList(),"gradeId");


        List<KeyDateVo> periodDateVoList=new ArrayList<>();
        for (Long periodId:periodIds){
            KeyDateVo keyDateVo=new KeyDateVo();
            keyDateVo.setEndDate(endDate);
            keyDateVo.setStartDate(startDate);
            keyDateVo.setKey(periodId.toString());
            periodDateVoList.add(keyDateVo);
        }


        List<Period> periodList=periodService.findByIdsOrderByPeriodNo(periodIds);
        List<Period> allPeriod=new ArrayList<>();
        allPeriod.addAll(periodList);

        List<BaseGrade> baseGradeList=periodRegVo.getBaseGradeList();
        List<Long> allPeriodIds=new ArrayList<>();
        allPeriodIds.addAll(periodIds);
        if (needWithPeriod==1){

            List<Long> withPeriodIds=BeanUtils.toList(periodList,"withPeriodId");
            if (Utils.checkListNotEmpty(withPeriodIds)){
                List<Period> withPeriods=periodService.findByIdsOrderByPeriodNo(withPeriodIds);
                Map<Long,Period> withPeriodMap=BeanUtils.toMap(withPeriods,"periodId");

                allPeriodIds.addAll(withPeriodIds);
                List<PeriodGradeDate> periodGradeDateList=periodGradeDateService.findByPeriodsGradeIds(allPeriodIds,gradeIds);
                Map<Long,List<PeriodGradeDate>> periodGradeDateMap=BeanUtils.toGroup(periodGradeDateList,"periodId");
                for (Period period:periodList){

                    Long withPeriodId=period.getWithPeriodId();
                    if (periodIds.contains(withPeriodId)){
                        continue;
                    }
                    Period withPeriod=withPeriodMap.get(withPeriodId);
                    if (withPeriod!=null){
                        allPeriod.add(withPeriod);
                    }
                    List<PeriodGradeDate> onePeriodGradeDateList=periodGradeDateMap.get(period.getPeriodId());
                    List<PeriodGradeDate> withPeriodGradeDateList=periodGradeDateMap.get(withPeriodId);
                    Map<Long,PeriodGradeDate> onePeriodGradeDateMap=BeanUtils.toMap(onePeriodGradeDateList,"gradeId");
                    Map<Long,PeriodGradeDate> withPeriodGradeDateMap=BeanUtils.toMap(withPeriodGradeDateList,"gradeId");
                    for (BaseGrade baseGrade:baseGradeList){
                        PeriodGradeDate onePeriodGradeDate=onePeriodGradeDateMap.get(baseGrade.getGradeId());
                        if (onePeriodGradeDate==null){
                            continue;
                            //throw new BusException(period.getPeriodName()+baseGrade.getGradeName()+"未设置开课日期");
                        }
                        PeriodGradeDate withPeriodGradeDate=withPeriodGradeDateMap.get(baseGrade.getGradeId());
                        if (withPeriodGradeDate==null){
                            continue;
                            //throw new BusException(period.getPeriodName()+"的同期"+withPeriod.getPeriodName()+baseGrade.getGradeName()+"未设置开课日期");
                        }
                        int timeTnterval=TimeUtils.daysOfTwo(onePeriodGradeDate.getPeriodGradeDate(),endDate);

                        Date searchEndDate=TimeUtils.changeDateByNum(withPeriodGradeDate.getPeriodGradeDate(),timeTnterval);
                        KeyDateVo keyDateVo=new KeyDateVo();
                        keyDateVo.setKey(withPeriod.getPeriodId()+"_"+baseGrade.getGradeId());
                        keyDateVo.setEndDate(TimeUtils.changeOneDateLastTime(searchEndDate));
                        if (startDate!=null){
                            Date searchStartDate=TimeUtils.changeDateByNum(searchEndDate,TimeUtils.daysOfTwo(endDate,startDate));
                            keyDateVo.setStartDate(searchStartDate);
                        }
                        periodDateVoList.add(keyDateVo);

                    }
                }
            }
        }
        Map<String,KeyDateVo> periodDateVoMap=BeanUtils.toMap(periodDateVoList,"key");
        List<StudentRefund> realStudentRefundList=new ArrayList<>();
        if (needFindRefund==1){
            StudentRefundQueryVo studentRefundQueryVo=new StudentRefundQueryVo();
            studentRefundQueryVo.setAreaTeamId(areaTeamId);
            studentRefundQueryVo.setStatus(1);
            studentRefundQueryVo.setGradeIds(gradeIds);
            studentRefundQueryVo.setSubjectIds(subjectIds);
            if (needWithPeriod==0){
                studentRefundQueryVo.setStartAuditTime(startDate);
                studentRefundQueryVo.setEndAuditTime(endDate);
                realStudentRefundList=studentRefundService.findListByQueryVo(studentRefundQueryVo,busTeamIds,allPeriodIds,0);
            }else {
                List<StudentRefund> studentRefundList=studentRefundService.findListByQueryVo(studentRefundQueryVo,busTeamIds,allPeriodIds,0);
                Map<Long, List<StudentRefund>> studentRefundMap = BeanUtils.toGroup(studentRefundList,"periodId");
                for (Map.Entry<Long,List<StudentRefund>> entry:studentRefundMap.entrySet()){
                    Long periodId=entry.getKey();
                    List<StudentRefund> studentRefunds=entry.getValue();
                    KeyDateVo periodDateVo=periodDateVoMap.get(periodId.toString());
                    if (periodDateVo!=null){
                        for (StudentRefund studentRefund:studentRefunds){
                            if ((periodDateVo.getStartDate()==null || studentRefund.getAuditTime().after(periodDateVo.getStartDate())) && (periodDateVo.getEndDate()==null || studentRefund.getAuditTime().before(periodDateVo.getEndDate()))){
                                realStudentRefundList.add(studentRefund);
                            }
                        }
                    }else {
                        for (StudentRefund studentRefund:studentRefunds){
                            if (studentRefund.getAuditTime()==null){
                                continue;
                            }
                            periodDateVo=periodDateVoMap.get(studentRefund.getPeriodId()+"_"+studentRefund.getGradeId());
                            if (periodDateVo==null){
                                continue;
                            }
                            if ((periodDateVo.getStartDate()==null || studentRefund.getAuditTime().after(periodDateVo.getStartDate())) && (periodDateVo.getEndDate()==null || studentRefund.getAuditTime().before(periodDateVo.getEndDate()))){
                                realStudentRefundList.add(studentRefund);
                            }
                        }
                    }
                }
            }
        }
        periodRegVo.setStudentRefundList(realStudentRefundList);



        List<MergeStudentRegDetail> realMergeStudentRegDetailList=new ArrayList<>();
        PeriodQueryRegVo periodQueryRegVo=new PeriodQueryRegVo();
        periodQueryRegVo.setAreaTeamId(areaTeamId);
        periodQueryRegVo.setSubjectIds(subjectIds);
        periodQueryRegVo.setRegStatuses(regStatuses);

        List<MergeStudentRegDetail> mergeStudentRegDetailList = mergeStudentRegDetailService.findListByBusTeamIdsPeriodsGradeIds(busTeamIds, allPeriodIds, gradeIds, periodQueryRegVo, "busTeamId", "periodId", "gradeId", "studentId", "studentState", "payAmount", "srcTotalAmount", "totalAmount", "regStatus", "subjectId", "classId", "refundAmount", "createTime");
        Map<Long, List<MergeStudentRegDetail>> periodRegMap = BeanUtils.toGroup(mergeStudentRegDetailList, "periodId");

        for (Map.Entry<Long, List<MergeStudentRegDetail>> entry : periodRegMap.entrySet()) {
            Long periodId = entry.getKey();
            List<MergeStudentRegDetail> oneMergeStudentRegDetails = entry.getValue();
            KeyDateVo periodDateVo = periodDateVoMap.get(periodId.toString());
            if (periodDateVo != null) {
                for (MergeStudentRegDetail mergeStudentRegDetail : oneMergeStudentRegDetails) {
                    if ((periodDateVo.getStartDate() == null || mergeStudentRegDetail.getCreateTime().after(periodDateVo.getStartDate())) && (periodDateVo.getEndDate() == null || mergeStudentRegDetail.getCreateTime().before(periodDateVo.getEndDate()))) {
                        realMergeStudentRegDetailList.add(mergeStudentRegDetail);
                    }
                }
            } else {
                for (MergeStudentRegDetail mergeStudentRegDetail : oneMergeStudentRegDetails) {
                    periodDateVo = periodDateVoMap.get(mergeStudentRegDetail.getPeriodId() + "_" + mergeStudentRegDetail.getGradeId());
                    if (periodDateVo==null){
                        continue;
                    }
                    if ((periodDateVo.getStartDate() == null || mergeStudentRegDetail.getCreateTime().after(periodDateVo.getStartDate())) && (periodDateVo.getEndDate() == null || mergeStudentRegDetail.getCreateTime().before(periodDateVo.getEndDate()))) {
                        realMergeStudentRegDetailList.add(mergeStudentRegDetail);
                    }
                }
            }
        }
        periodRegVo.setMergeStudentRegDetailList(realMergeStudentRegDetailList);


        if (Utils.checkListNotEmpty(realStudentRefundList)){
            Map<String, List<StudentRefund>> refundRegMap = new HashMap<>();
            if (realStudentRefundList != null) {
                List<MergeStudentRegDetail> mergeStudentRegDetails=new ArrayList<>();

                for (StudentRefund studentRefund : realStudentRefundList) {
                    String key = studentRefund.getStudentId() + "_" + studentRefund.getClassId();
                    List<StudentRefund> studentRefunds = refundRegMap.get(key);
                    if (studentRefunds == null) {
                        studentRefunds = new ArrayList<>();
                        refundRegMap.put(key, studentRefunds);
                    }
                    studentRefunds.add(studentRefund);
                }
                for (MergeStudentRegDetail mergeStudentRegDetail:mergeStudentRegDetailList){
                    String key=mergeStudentRegDetail.getStudentId()+"_"+mergeStudentRegDetail.getClassId();
                    if (refundRegMap.containsKey(key)){
                        mergeStudentRegDetails.add(mergeStudentRegDetail);
                    }
                }
                periodRegVo.setRefundRegDetails(mergeStudentRegDetails);
                periodRegVo.setRefundRegMap(refundRegMap);
            }
        }



        periodRegVo.setPeriodList(allPeriod==null?new ArrayList<>():allPeriod);
        return periodRegVo;
    }

    public static SXSSFWorkbook amountBranchPerson2excel(AmountBranchPerson amountBranchPerson) {
        SXSSFWorkbook excel = new SXSSFWorkbook();

        List<AmountDataVo> amountList=amountBranchPerson.getAmountList();
        List<BranchDataVo> branchList=amountBranchPerson.getBranchList();
        List<PersonDataVo> personList =amountBranchPerson.getPersonList();

        List<AmountDetailVo> amountDetailList = toAmountDetailList(amountList);
        excel=fillAmountExcel(excel,amountDetailList,"金额");

        List<BranchDetailVo> branchDetailList = toBranchDetailList(branchList);
        excel=fillBranchExcel(excel,branchDetailList,"科数");

        List<PersonDetailVo> personDetailList = toPersonDetailList(personList);
        excel=fillPersonExcel(excel,personDetailList,"人数");
        return excel;
    }

    private static  List<BranchDetailVo> toBranchDetailList(List<BranchDataVo> list){
        List<BranchDetailVo> amountBranchPersonDetailVoList=new ArrayList<>();
        for (BranchDataVo amountBranchPersonDataVo:list){
            List<BranchDetailVo> tempList=amountBranchPersonDataVo.getAmountBranchPersonDetailVoList();
            if (tempList!=null && tempList.size()>0){
                amountBranchPersonDetailVoList.addAll(tempList);
            }
        }
        Collections.sort(amountBranchPersonDetailVoList, new Comparator<BranchDetailVo>() {
            @Override
            public int compare(BranchDetailVo o1, BranchDetailVo o2) {
                return o1.getDateStr().compareTo(o2.getDateStr());
            }
        });
        return amountBranchPersonDetailVoList;
    }


    private static  List<PersonDetailVo> toPersonDetailList(List<PersonDataVo> list){
        List<PersonDetailVo> amountBranchPersonDetailVoList=new ArrayList<>();
        for (PersonDataVo amountBranchPersonDataVo:list){
            List<PersonDetailVo> tempList=amountBranchPersonDataVo.getAmountBranchPersonDetailVoList();
            if (tempList!=null && tempList.size()>0){
                amountBranchPersonDetailVoList.addAll(tempList);
            }
        }
        Collections.sort(amountBranchPersonDetailVoList, new Comparator<PersonDetailVo>() {
            @Override
            public int compare(PersonDetailVo o1, PersonDetailVo o2) {
                return o1.getDateStr().compareTo(o2.getDateStr());
            }
        });
        return amountBranchPersonDetailVoList;
    }




    private static  List<AmountDetailVo> toAmountDetailList(List<AmountDataVo> list){
        List<AmountDetailVo> amountBranchPersonDetailVoList=new ArrayList<>();
        for (AmountDataVo amountBranchPersonDataVo:list){
            List<AmountDetailVo> tempList=amountBranchPersonDataVo.getAmountBranchPersonDetailVoList();
            if (tempList!=null && tempList.size()>0){
                amountBranchPersonDetailVoList.addAll(tempList);
            }
        }
        Collections.sort(amountBranchPersonDetailVoList, new Comparator<AmountDetailVo>() {
            @Override
            public int compare(AmountDetailVo o1, AmountDetailVo o2) {
                return o1.getDateStr().compareTo(o2.getDateStr());
            }
        });
        return amountBranchPersonDetailVoList;
    }






    private  static  SXSSFWorkbook  fillAmountExcel(SXSSFWorkbook excel,List<AmountDetailVo> amountBranchPersonDetailVoList,String sheetName){
        SXSSFSheet sheet = excel.createSheet(sheetName);
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"日期","业务组","新生","老生","续读生","总计"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        for (AmountDetailVo amountBranchPersonDetailVo:amountBranchPersonDetailVoList){
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getDateStr());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getBusTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getNewStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getOldStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getSeqStepStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getTotalNum());
        }
        return excel;
    }


    private  static  SXSSFWorkbook  fillBranchExcel(SXSSFWorkbook excel,List<BranchDetailVo> amountBranchPersonDetailVoList,String sheetName){
        SXSSFSheet sheet = excel.createSheet(sheetName);
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"日期","业务组","新生","老生","续读生","总计"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        for (BranchDetailVo amountBranchPersonDetailVo:amountBranchPersonDetailVoList){
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getDateStr());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getBusTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getNewStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getOldStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getSeqStepStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getTotalNum());
        }
        return excel;
    }

    private  static  SXSSFWorkbook  fillPersonExcel(SXSSFWorkbook excel,List<PersonDetailVo> amountBranchPersonDetailVoList,String sheetName){
        SXSSFSheet sheet = excel.createSheet(sheetName);
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"日期","业务组","新生","老生","续读生","总计"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        for (PersonDetailVo amountBranchPersonDetailVo:amountBranchPersonDetailVoList){
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getDateStr());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getBusTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getNewStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getOldStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getSeqStepStudentNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(amountBranchPersonDetailVo.getTotalNum());
        }
        return excel;
    }




    public static SXSSFWorkbook seniorComletionRate2excel(List<SeniorCompletionRateVo> seniorCompletionRateVos) {
        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("班主任科数完成率");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"业务组", "期数", "班主任","本期人数", "本期科数", "顺期科数","顺期人数", "顺期续读率", "目标顺期续读率", "跨期科数","跨期人数", "跨期续读率", "目标跨期续读率"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;


        SXSSFSheet sheet1 = excel.createSheet("班主任续读详情");
        SXSSFRow firstRow1 = sheet1.createRow(0);
        String[] titles1 = new String[]{"期数", "班主任所在业务组", "班主任", "学生姓名","学生电话号码", "本期在读班级", "顺期续读情况", "跨期续读情况","顺期拓科情况","跨期拓科情况"};
        int rowNum1 = 1;
        for (int i = 0; i < titles1.length; i++) {
            firstRow1.createCell(i).setCellValue(titles1[i]);
        }


        for (SeniorCompletionRateVo seniorCompletionRateVo : seniorCompletionRateVos) {
            int cellNum = 0;

            SXSSFRow row = sheet.createRow(rowNum);
            rowNum++;

            SXSSFCell cell = row.createCell(cellNum);
            cell.setCellValue(seniorCompletionRateVo.getBusTeamName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(seniorCompletionRateVo.getPeriodName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(seniorCompletionRateVo.getTeacherName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(seniorCompletionRateVo.getRealPersonNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(seniorCompletionRateVo.getNowPeriodNum())));
            cellNum++;


            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(seniorCompletionRateVo.getSequentialNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(seniorCompletionRateVo.getSeqPersonNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.getPercent(Utils.formatString(seniorCompletionRateVo.getSequentialNum()), Utils.formatString(seniorCompletionRateVo.getNowPeriodNum()), 2));
            cellNum++;


            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.formatPercentString(seniorCompletionRateVo.getTargetSequentialNum()));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(seniorCompletionRateVo.getStepNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(seniorCompletionRateVo.getStepPersonNum())));
            cellNum++;


            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.getPercent(Utils.formatString(seniorCompletionRateVo.getStepNum()), Utils.formatString(seniorCompletionRateVo.getNowPeriodNum()), 2));
            cellNum++;


            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.formatPercentString(seniorCompletionRateVo.getTargetStepNum()));

            for (SeniorRegDetailVo seniorRegDetailVo:seniorCompletionRateVo.getSeniorRegDetailVoList()){
                int cellNum1 = 0;
                SXSSFRow row1 = sheet1.createRow(rowNum1);
                rowNum1++;
                SXSSFCell cell1 = row1.createCell(cellNum1++);
                cell1.setCellValue(StringUtils.defaultString(seniorRegDetailVo.getPeriodName()));

                cell1 = row1.createCell(cellNum1++);
                cell1.setCellValue(StringUtils.defaultString(seniorRegDetailVo.getSeniorBusTeamName()));

                cell1 = row1.createCell(cellNum1++);
                cell1.setCellValue(StringUtils.defaultString(seniorRegDetailVo.getSeniorName()));

                cell1 = row1.createCell(cellNum1++);
                cell1.setCellValue(StringUtils.defaultString(seniorRegDetailVo.getStudentName()));

                cell1 = row1.createCell(cellNum1++);
                cell1.setCellValue(StringUtils.defaultString(seniorRegDetailVo.getStudentPhoneNo()));


                cell1 = row1.createCell(cellNum1++);
                cell1.setCellValue(StringUtils.defaultString(seniorRegDetailVo.getNowPeriodDetail()));

                cell1 = row1.createCell(cellNum1++);
                cell1.setCellValue(StringUtils.defaultString(seniorRegDetailVo.getSequentialDetail()));

                cell1 = row1.createCell(cellNum1++);
                cell1.setCellValue(StringUtils.defaultString(seniorRegDetailVo.getStepDetail()));

                cell1 = row1.createCell(cellNum1++);
                cell1.setCellValue(StringUtils.defaultString(seniorRegDetailVo.getSeqDevelopDetail()));

                cell1 = row1.createCell(cellNum1++);
                cell1.setCellValue(StringUtils.defaultString(seniorRegDetailVo.getStepDevelopDetail()));
            }


        }

        return excel;
    }



    public static SXSSFWorkbook studentContinueRegDetail2excel(SXSSFWorkbook excel ,List<StudentContinueRegDetailVo> studentContinueRegDetailVoList) {

        SXSSFSheet sheet = excel.createSheet("续读详情合并");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{ "期数", "班主任","学生姓名", "学生电话号码", "本期在读班级","顺期续读情况", "跨期续读情况", "顺期拓科情况", "跨期拓科情况"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;


        for (StudentContinueRegDetailVo studentContinueRegDetailVo : studentContinueRegDetailVoList) {
            int cellNum = 0;

            SXSSFRow row = sheet.createRow(rowNum);
            rowNum++;

            SXSSFCell cell = row.createCell(cellNum);
            cell.setCellValue(studentContinueRegDetailVo.getPeriodName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(StringUtils.defaultString(studentContinueRegDetailVo.getSeniorNames()));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(StringUtils.defaultString(studentContinueRegDetailVo.getStudentName()));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(StringUtils.defaultString(studentContinueRegDetailVo.getStudentPhoneNo()));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(StringUtils.defaultString(studentContinueRegDetailVo.getNowPeriodDetail()));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(StringUtils.defaultString(studentContinueRegDetailVo.getSequentialDetail()));
            cellNum++;


            cell = row.createCell(cellNum);
            cell.setCellValue(StringUtils.defaultString(studentContinueRegDetailVo.getStepDetail()));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(StringUtils.defaultString(studentContinueRegDetailVo.getSeqDevelopDetail()));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(StringUtils.defaultString(studentContinueRegDetailVo.getStepDevelopDetail()));
            cellNum++;



        }

        return excel;
    }


    public static SXSSFWorkbook studentOnlyStepContinueRegDetail2excel(SXSSFWorkbook excel ,List<SeniorCompletionRateVo> seniorCompletionRateVos) {
        /*key :"periodId_seniorId,只跨期的人数,子 key ：“stepBranchNum”,"stepPersonNum""*/
        Map<String,Map<String,Integer>> map=new HashMap<>();
        if (seniorCompletionRateVos!=null){
            for (SeniorCompletionRateVo seniorCompletionRateVo:seniorCompletionRateVos){
                List<SeniorRegDetailVo> seniorRegDetailVos=seniorCompletionRateVo.getSeniorRegDetailVoList();
                if (seniorRegDetailVos!=null){
                    for (SeniorRegDetailVo seniorRegDetailVo:seniorRegDetailVos){
                        String key=seniorRegDetailVo.getPeriodId()+"_"+seniorRegDetailVo.getSeniorId();
                /*没顺期(包括顺期拓科)，跨期（包括跨期拓科）*/
                        if (Utils.checkListEmpty(seniorRegDetailVo.getSeqRegIds()) && StringUtils.isEmpty(seniorRegDetailVo.getSeqDevelopDetail()) &&(Utils.checkListNotEmpty(seniorRegDetailVo.getStepRegIds()) || StringUtils.isNotEmpty(seniorRegDetailVo.getStepDevelopDetail()))){
                            Map<String,Integer> subMap=map.get(key);
                            if (subMap==null){
                                subMap=new HashMap<>();
                                subMap.put("stepBranchNum",0);
                                subMap.put("stepPersonNum",0);
                                map.put(key,subMap);
                            }
                            int stepNum=seniorRegDetailVo.getStepRegIds()==null?0:seniorRegDetailVo.getStepRegIds().size();
                            int stepDevelopNum=StringUtils.isEmpty(seniorRegDetailVo.getStepDevelopDetail())?0:seniorRegDetailVo.getStepDevelopDetail().split(",").length;
                            subMap.put("stepBranchNum",subMap.get("stepBranchNum")+stepNum+stepDevelopNum);
                            subMap.put("stepPersonNum",subMap.get("stepPersonNum")+1);
                        }
                    }
                }



            }
        }


        SXSSFSheet sheet = excel.createSheet("班主任跨期科数统计");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{ "业务组", "期数","班主任", "本期人数", "本期科数","跨期科数", "跨期人数"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;
        if (seniorCompletionRateVos!=null){
            for (SeniorCompletionRateVo seniorCompletionRateVo:seniorCompletionRateVos){
                String key=seniorCompletionRateVo.getPeriodId()+"_"+seniorCompletionRateVo.getTeacherId();
                int cellNum = 0;

                SXSSFRow row = sheet.createRow(rowNum);
                rowNum++;

                SXSSFCell cell = row.createCell(cellNum++);
                cell.setCellValue(seniorCompletionRateVo.getBusTeamName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(seniorCompletionRateVo.getPeriodName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(seniorCompletionRateVo.getTeacherName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(seniorCompletionRateVo.getRealPersonNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(seniorCompletionRateVo.getNowPeriodNum());

                int stepBranchNum=0;
                int stepPersonNum=0;
                Map<String,Integer> subMap=map.get(key);
                if (subMap!=null){
                    stepBranchNum=subMap.get("stepBranchNum");
                    stepPersonNum=subMap.get("stepPersonNum");
                }

                cell = row.createCell(cellNum++);
                cell.setCellValue(stepBranchNum);

                cell = row.createCell(cellNum++);
                cell.setCellValue(stepPersonNum);

            }
        }


        return excel;
    }













    public static SXSSFWorkbook gradeCompletionRate2excel(List<GradeCompletionRateVo> gradeCompletionRateVoList) {
        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("年级科数完成率");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"区域", "业务组", "期数", "年级",
                "实际新生科数",  "实际老生科数", "实际新老生科数","目标新老生科数", "新老生科数完成率", "本期科数", "本期人数","顺期科数","顺期人数", "顺期续读率", "目标顺期续读率", "跨期科数","跨期人数", "跨期续读率", "目标跨期续读率"};

        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;
        for (GradeCompletionRateVo gradeCompletionRateVo : gradeCompletionRateVoList) {
            int cellNum = 0;

            SXSSFRow row = sheet.createRow(rowNum);
            rowNum++;
            SXSSFCell cell = row.createCell(cellNum);
            cell.setCellValue(gradeCompletionRateVo.getAreaTeamName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(gradeCompletionRateVo.getBusTeamName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(gradeCompletionRateVo.getPeriodName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(gradeCompletionRateVo.getGradeName());
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(gradeCompletionRateVo.getRealNewStudentNum())));
            cellNum++;


            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(gradeCompletionRateVo.getRealOldStudentNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(gradeCompletionRateVo.getRealNewOldStudentNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(gradeCompletionRateVo.getTargetNewOldStudentNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.getPercent(Utils.formatString(gradeCompletionRateVo.getRealNewOldStudentNum()), gradeCompletionRateVo.getTargetNewOldStudentNum(), 2));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(gradeCompletionRateVo.getNowPeriodNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(gradeCompletionRateVo.getNowPersonNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(gradeCompletionRateVo.getSequentialNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(gradeCompletionRateVo.getSeqPersonNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.getPercent(Utils.formatString(gradeCompletionRateVo.getSequentialNum()), Utils.formatString(gradeCompletionRateVo.getNowPeriodNum()), 2));
            cellNum++;


            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.formatPercentString(gradeCompletionRateVo.getTargetSequentialNum()));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(gradeCompletionRateVo.getStepNum())));
            cellNum++;

            cell = row.createCell(cellNum);
            cell.setCellType(CellType.NUMERIC);
            cell.setCellValue(Integer.parseInt(Utils.formatString(gradeCompletionRateVo.getStepPersonNum())));
            cellNum++;


            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.getPercent(Utils.formatString(gradeCompletionRateVo.getStepNum()), Utils.formatString(gradeCompletionRateVo.getNowPeriodNum()), 2));
            cellNum++;


            cell = row.createCell(cellNum);
            cell.setCellValue(Utils.formatPercentString(gradeCompletionRateVo.getTargetStepNum()));
        }
        return excel;
    }




    private List<CounselorBranchBonusVo> toCounselorBranchBonusList(List<Teacher> teacherList, List<Period> periodList, List<MergeStudentRegDetail> mergeStudentRegDetailList, Integer bigLectureNum) {
        List<CounselorBranchBonusVo> counselorBranchBonusVoList = new ArrayList<CounselorBranchBonusVo>(teacherList.size());
        Map<Long,List<MergeStudentRegDetail>> counselorRegMap=BeanUtils.toGroup(mergeStudentRegDetailList,"counselorId");
        for (Teacher teacher : teacherList) {
            List<MergeStudentRegDetail> counselorRegList=counselorRegMap.get(teacher.getTeacherId());
            Map<Long,List<MergeStudentRegDetail>> counselorPeriodRegMap=BeanUtils.toGroup(counselorRegList,"periodId");
            for (Period period : periodList) {
                List<MergeStudentRegDetail> counselorPeriodRegList=counselorPeriodRegMap.get(period.getPeriodId());
                counselorBranchBonusVoList.add(toCounselorBranchBonusVo(teacher, period, counselorPeriodRegList, bigLectureNum));
            }
        }
        return counselorBranchBonusVoList;
    }

    private CounselorBranchBonusVo toCounselorBranchBonusVo(Teacher teacher, Period period, List<MergeStudentRegDetail> mergeStudentRegDetailList, Integer bigLectureNum) {

        CounselorBranchBonusVo counselorBranchBonusVo = new CounselorBranchBonusVo();
        counselorBranchBonusVo.setAreaTeamId(teacher.getAreaTeamId());
        counselorBranchBonusVo.setAreaTeamName(teacher.getAreaTeamName());
        counselorBranchBonusVo.setBusTeamId(teacher.getBusTeamId());
        counselorBranchBonusVo.setBusTeamName(teacher.getBusTeamName());
        counselorBranchBonusVo.setPeriodId(period.getPeriodId());
        counselorBranchBonusVo.setPeriodName(period.getPeriodName());
        counselorBranchBonusVo.setTeacherId(teacher.getTeacherId());
        counselorBranchBonusVo.setTeacherName(teacher.getTeacherName());
        Map<String,CounselorRegDetail> map=new HashMap<>();
        if (mergeStudentRegDetailList !=null){
            for (MergeStudentRegDetail mergeStudentRegDetail : mergeStudentRegDetailList){

                Long campusId= mergeStudentRegDetail.getCampusId()==null?1L: mergeStudentRegDetail.getCampusId();
                String key=campusId+"_"+ mergeStudentRegDetail.getStudentId()+"_"+ mergeStudentRegDetail.getGradeId();
                CounselorRegDetail counselorRegDetail=map.get(key);
                if (counselorRegDetail == null) {
                    counselorRegDetail = new CounselorRegDetail();
                    counselorRegDetail.setBusTeamId(mergeStudentRegDetail.getBusTeamId());
                    counselorRegDetail.setBusTeamName(mergeStudentRegDetail.getBusTeamName());
                    counselorRegDetail.setPeriodId(mergeStudentRegDetail.getPeriodId());
                    counselorRegDetail.setPeriodName(mergeStudentRegDetail.getPeriodName());
                    counselorRegDetail.setTeacherId(mergeStudentRegDetail.getCounselorId());
                    counselorRegDetail.setTeacherName(mergeStudentRegDetail.getCounselorName());
                    counselorRegDetail.setStudentId(mergeStudentRegDetail.getStudentId());
                    counselorRegDetail.setStudentPhoneNo(mergeStudentRegDetail.getStudentPhoneNo());
                    counselorRegDetail.setRelativeType(mergeStudentRegDetail.getStudentState());
                    counselorRegDetail.setStudentName(mergeStudentRegDetail.getStudentName());
                    counselorRegDetail.setCampusId(campusId);
                    counselorRegDetail.setCampusName(mergeStudentRegDetail.getCampusName());
                    counselorRegDetail.setStudentNo(mergeStudentRegDetail.getStudentNo());
                    counselorRegDetail.setStudentGradeName(mergeStudentRegDetail.getStudentGradeName());
                    counselorRegDetail.setGradeId(mergeStudentRegDetail.getGradeId());
                    counselorRegDetail.setGradeName(mergeStudentRegDetail.getGradeName());
                }

                if (mergeStudentRegDetail.getStudentState()==0){
                    if (mergeStudentRegDetail.getLectureNum()>bigLectureNum){
                        counselorBranchBonusVo.setBigRealNewStudentNum(counselorBranchBonusVo.getBigRealNewStudentNum()+1);
                        counselorRegDetail.setBigLectureNum(counselorRegDetail.getBigLectureNum() + 1);
                    }else {
                        counselorBranchBonusVo.setLessRealNewStudentNum(counselorBranchBonusVo.getLessRealNewStudentNum()+1);
                        counselorRegDetail.setLessLectureNum(counselorRegDetail.getLessLectureNum() + 1);
                    }
                }else if (mergeStudentRegDetail.getStudentState()==1){
                    if (mergeStudentRegDetail.getLectureNum()>bigLectureNum){
                        counselorBranchBonusVo.setBigRealOldStudentNum(counselorBranchBonusVo.getBigRealOldStudentNum()+1);
                        counselorRegDetail.setBigLectureNum(counselorRegDetail.getBigLectureNum() + 1);
                    }else {
                        counselorBranchBonusVo.setLessRealOldStudentNum(counselorBranchBonusVo.getLessRealOldStudentNum()+1);
                        counselorRegDetail.setLessLectureNum(counselorRegDetail.getLessLectureNum() + 1);
                    }
                }

                map.put(key, counselorRegDetail);
            }
        }

        Collection<CounselorRegDetail> valueCollection = map.values();
        List<CounselorRegDetail> counselorRegDetailList = new ArrayList<CounselorRegDetail>(valueCollection);
        counselorBranchBonusVo.setCounselorRegDetailList(counselorRegDetailList);
        return counselorBranchBonusVo;
    }







    @Override
    public Page<TeacherCommissionDetail> findTeacherCommissionPage(TeacherQueryVo teacherQueryVo,DataPermission dataPermission, List<PeriodTypeQueryVo> periodTypeQueryVoList,int pageNo,int pageSize) {
        Page<Teacher> teacherPage=teacherService.findTeacherByQueryForPage(teacherQueryVo,dataPermission,pageNo,pageSize);
        Page<TeacherCommissionDetail> teacherCommissionDetailPage=Utils.newPage(teacherPage);
        List<Teacher> teacherList=teacherPage.getRecords();
        /*key="teacherId_0 新生， teacherId_1 老生， teacherId_2 顺期,teacherId_3 跨期"*/
        Map<String,Integer> teacherCommissionMap=new HashMap<>();
        if (teacherList!=null){
            List<Long> teacherIds=BeanUtils.toList(teacherList,"teacherId");
            if (periodTypeQueryVoList!=null){
                List<Long> newOrOldPeriodIdList=new ArrayList<>(periodTypeQueryVoList.size());
                List<Long> seqOrStepPeriodIdList=new ArrayList<>(periodTypeQueryVoList.size());
                Date newOrOldMinDate=null;
                Date newOrOldMaxDate=null;
                Date seqOrStepMinDate=null;
                Date seqOrStepMaxDate=null;
                List<Integer> newOrOldState=new ArrayList<>();
                List<Integer> seqOrStepState=new ArrayList<>();
                Map<String,TimeTypeQueryVo> timeTypeQueryVoMap=new HashMap<>();
                for (PeriodTypeQueryVo periodTypeQueryVo:periodTypeQueryVoList){

                    List<TimeTypeQueryVo> timeTypeQueryVoList=periodTypeQueryVo.getTimeTypeQueryVoList();
                    if (timeTypeQueryVoList!=null){
                        for (TimeTypeQueryVo timeTypeQueryVo:timeTypeQueryVoList){
                            String key=periodTypeQueryVo.getPeriodId()+"_"+timeTypeQueryVo.getType();
                            if (!timeTypeQueryVoMap.containsKey(key)){
                                timeTypeQueryVoMap.put(key,timeTypeQueryVo);
                            }
                            if (timeTypeQueryVo.getType()==0 || timeTypeQueryVo.getType()==1){
                                newOrOldPeriodIdList.add(periodTypeQueryVo.getPeriodId());
                                if (timeTypeQueryVo.getEndDate()!=null){
                                    timeTypeQueryVo.setEndDate(TimeUtils.changeOneDateLastTime(timeTypeQueryVo.getEndDate()));
                                }

                                if (newOrOldMinDate==null || (timeTypeQueryVo.getStartDate()!=null && timeTypeQueryVo.getStartDate().before(newOrOldMinDate))){
                                    newOrOldMinDate=timeTypeQueryVo.getStartDate();
                                }

                                if (newOrOldMaxDate==null || (timeTypeQueryVo.getEndDate()!=null && timeTypeQueryVo.getEndDate().after(newOrOldMaxDate))){
                                    newOrOldMaxDate=timeTypeQueryVo.getEndDate();
                                }
                                if (timeTypeQueryVo.getType()==0){
                                    newOrOldState.add(0);
                                }else if (timeTypeQueryVo.getType()==1){
                                    newOrOldState.add(1);
                                }
                            }

                            if (timeTypeQueryVo.getType()==2 || timeTypeQueryVo.getType()==3){
                                seqOrStepPeriodIdList.add(periodTypeQueryVo.getPeriodId());
                                if (timeTypeQueryVo.getEndDate()!=null){
                                    timeTypeQueryVo.setEndDate(TimeUtils.changeOneDateLastTime(timeTypeQueryVo.getEndDate()));
                                }

                                if (seqOrStepMinDate==null || (timeTypeQueryVo.getStartDate()!=null && timeTypeQueryVo.getStartDate().before(seqOrStepMinDate))){
                                    seqOrStepMinDate=timeTypeQueryVo.getStartDate();
                                }

                                if (seqOrStepMaxDate==null || (timeTypeQueryVo.getEndDate()!=null && timeTypeQueryVo.getEndDate().after(seqOrStepMaxDate))){
                                    seqOrStepMaxDate=timeTypeQueryVo.getEndDate();
                                }
                                if (timeTypeQueryVo.getType()==2){
                                    seqOrStepState.add(2);
                                }else {
                                    seqOrStepState.add(3);
                                }
                            }
                        }
                    }
                }
                newOrOldState=Utils.removeDuplicate(newOrOldState);
                newOrOldPeriodIdList=Utils.removeDuplicate(newOrOldPeriodIdList);
                List<MergeStudentRegDetail> mergeStudentRegDetailList =null;
                if (newOrOldState!=null && newOrOldState.size()>0){
                    PeriodQueryRegVo periodQueryRegVo=new PeriodQueryRegVo();
                    periodQueryRegVo.setStartPayTime(newOrOldMinDate);
                    periodQueryRegVo.setEndPayTime(newOrOldMaxDate);
                    periodQueryRegVo.setRegStatus(0);
                    periodQueryRegVo.setChargingStatus(2);
                    mergeStudentRegDetailList = mergeStudentRegDetailService.findByCounselorIdsPeriodIdsStates(teacherIds, newOrOldPeriodIdList, newOrOldState, periodQueryRegVo, studentRegDetailColumns);
                    if (mergeStudentRegDetailList !=null){
                        for (MergeStudentRegDetail mergeStudentRegDetail : mergeStudentRegDetailList){
                            String key= mergeStudentRegDetail.getPeriodId()+"_"+ mergeStudentRegDetail.getStudentState();
                            TimeTypeQueryVo timeTypeQueryVo=timeTypeQueryVoMap.get(key);
                            if (timeTypeQueryVo!=null){
                                if ((timeTypeQueryVo.getStartDate()==null || mergeStudentRegDetail.getPayTime().after(timeTypeQueryVo.getStartDate())) && (timeTypeQueryVo.getEndDate()==null || mergeStudentRegDetail.getPayTime().before(timeTypeQueryVo.getEndDate()))){
                                    String  teacherCommissionKey= mergeStudentRegDetail.getCounselorId()+"_"+ mergeStudentRegDetail.getStudentState();
                                    teacherCommissionMap.put(teacherCommissionKey,teacherCommissionMap.get(teacherCommissionKey)==null?1:teacherCommissionMap.get(teacherCommissionKey)+1);
                                }
                            }
                        }
                    }
                }

                seqOrStepState=Utils.removeDuplicate(seqOrStepState);
                seqOrStepPeriodIdList=Utils.removeDuplicate(seqOrStepPeriodIdList);
                List<Period> periodList=periodService.findByIds(seqOrStepPeriodIdList);
                Map<Long,List<Long>> seqMap=new HashMap<>();
                Map<Long,List<Long>> stepMap=new HashMap<>();
                List<Long> seqStepList=new ArrayList<>();
                for (Period period:periodList){
                    Long periodId=period.getPeriodId();
                    Integer periodNo=period.getPeriodNo();
                    List<Period> seqStepPeriod = periodService.findNextByPeriodId(periodId, 2);
                    List<Long> useSeqPeriodIds=new ArrayList<>(seqStepPeriod==null?0:seqStepPeriod.size());
                    List<Long> useStepPeriodIds=new ArrayList<>(seqStepPeriod==null?0:seqStepPeriod.size());
                    for (Period temp:seqStepPeriod){
                        if (temp.getPeriodNo()-1==periodNo){
                            useSeqPeriodIds.add(temp.getPeriodId());
                        }
                        if (temp.getPeriodNo()-2==periodNo){
                            useStepPeriodIds.add(temp.getPeriodId());
                        }
                    }
                    seqStepList.addAll(useSeqPeriodIds);
                    seqStepList.addAll(useStepPeriodIds);
                    seqMap.put(periodId,useSeqPeriodIds);
                    stepMap.put(periodId,useStepPeriodIds);
                }

                if (seqOrStepState!=null && seqOrStepState.size()>0){
                    PeriodQueryRegVo periodQueryRegVo=new PeriodQueryRegVo();
                    periodQueryRegVo.setPeriodIds(seqOrStepPeriodIdList);
                    periodQueryRegVo.setSeniorIds(teacherIds);
                    RegRelativceQueryVo regRelativceQueryVo=new RegRelativceQueryVo();
                    regRelativceQueryVo.setStartPayTime(seqOrStepMinDate);
                    regRelativceQueryVo.setEndPayTime(seqOrStepMaxDate);
                    regRelativceQueryVo.setPeriodIds(seqStepList);
                    regRelativceQueryVo.setHaveRelative(1);
                    List<RegRelativeVo> regRelativeVoList=mergeStudentRegDetailService.queryRegRelative(periodQueryRegVo,regRelativceQueryVo);

                    Map<String,Integer> repeatMap=new HashMap<>();
                    if (regRelativeVoList!=null){
                        for (RegRelativeVo regRelativeVo:regRelativeVoList){
                            Long periodId=regRelativeVo.getPeriodId();
                            Long relativePeriodId=regRelativeVo.getRelativePeriodId();
                            Integer relativeType=-1;
                            List<Long> seqIdList=seqMap.get(periodId);
                            List<Long> stepIdList=stepMap.get(periodId);
                            if (seqIdList!=null && seqIdList.contains(relativePeriodId)){
                                relativeType=2;
                            }
                            if (stepIdList!=null && stepIdList.contains(relativePeriodId)){
                                relativeType=3;
                            }

                            String repeatKey = regRelativeVo.getSeniorId() + "_" + regRelativeVo.getPeriodId() + "_" + relativeType+"_"+regRelativeVo.getRelativeRegId();

                            String key=regRelativeVo.getPeriodId()+"_"+relativeType;
                            TimeTypeQueryVo timeTypeQueryVo=timeTypeQueryVoMap.get(key);
                            if (timeTypeQueryVo!=null){
                                if ((timeTypeQueryVo.getStartDate()==null || regRelativeVo.getRelativePayTime().after(timeTypeQueryVo.getStartDate())) && (timeTypeQueryVo.getEndDate()==null || regRelativeVo.getRelativePayTime().before(timeTypeQueryVo.getEndDate()))){
                                    String  teacherCommissionKey=regRelativeVo.getSeniorId()+"_"+relativeType;
                                    if (!repeatMap.containsKey(repeatKey)){
                                        teacherCommissionMap.put(teacherCommissionKey,teacherCommissionMap.get(teacherCommissionKey)==null?1:teacherCommissionMap.get(teacherCommissionKey)+1);
                                    }
                                    repeatMap.put(repeatKey,repeatMap.get(repeatKey)==null?0:repeatMap.get(repeatKey)+1);
                                }
                            }

                        }
                    }
                }
            }
            List<TeacherCommissionDetail> teacherCommissionDetailList=new ArrayList<>(teacherList.size());
            for (Teacher teacher:teacherList){
                Long teacherId=teacher.getTeacherId();
                TeacherCommissionDetail teacherCommissionDetail=new TeacherCommissionDetail();
                teacherCommissionDetail.setTeacherId(teacher.getTeacherId());
                teacherCommissionDetail.setTeacherName(teacher.getTeacherName());
                teacherCommissionDetail.setBusTeamId(teacher.getBusTeamId());
                teacherCommissionDetail.setBusTeamName(teacher.getBusTeamName());
                teacherCommissionDetail.setNewStudentNum(teacherCommissionMap.get(teacherId+"_"+"0")==null?0:teacherCommissionMap.get(teacherId+"_"+"0"));
                teacherCommissionDetail.setOldStudentNum(teacherCommissionMap.get(teacherId+"_"+"1")==null?0:teacherCommissionMap.get(teacherId+"_"+"1"));
                teacherCommissionDetail.setNewOldStudentNum(teacherCommissionDetail.getNewStudentNum()+teacherCommissionDetail.getOldStudentNum());
                teacherCommissionDetail.setSeqStudentNum(teacherCommissionMap.get(teacherId+"_"+"2")==null?0:teacherCommissionMap.get(teacherId+"_"+"2"));
                teacherCommissionDetail.setStepStudentNum(teacherCommissionMap.get(teacherId+"_"+"3")==null?0:teacherCommissionMap.get(teacherId+"_"+"3"));
                teacherCommissionDetail.setSeqStepStudentNum(teacherCommissionDetail.getSeqStudentNum()+teacherCommissionDetail.getStepStudentNum());

                teacherCommissionDetail.setNewOldStudentAmount(new BigDecimal(teacherCommissionDetail.getNewOldStudentNum()*20));
                teacherCommissionDetail.setSeqStepStudentAmount(new BigDecimal(teacherCommissionDetail.getSeqStepStudentNum()*10));
                teacherCommissionDetail.setTotalAmount(teacherCommissionDetail.getNewOldStudentAmount().add(teacherCommissionDetail.getSeqStepStudentAmount()));
                teacherCommissionDetailList.add(teacherCommissionDetail);
            }
            teacherCommissionDetailPage.setRecords(teacherCommissionDetailList);
        }

        return teacherCommissionDetailPage;
    }

    @Override
    public SXSSFWorkbook exportTeacherCommission(TeacherQueryVo teacherQueryVo, DataPermission dataPermission, List<PeriodTypeQueryVo> periodTypeQueryVoList) {
        Page<TeacherCommissionDetail> teacherCommissionDetailPage=this.findTeacherCommissionPage(teacherQueryVo,dataPermission,periodTypeQueryVoList,1,10000);
        SXSSFWorkbook excel=teacherCommission2excel(teacherCommissionDetailPage.getRecords());
        return excel;
    }

    public static SXSSFWorkbook teacherCommission2excel(List<TeacherCommissionDetail> teacherCommissionDetailList) {

        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("招生提成");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{ "姓名", "人事单位", "新生科数","老生科数", "新老生科数", "新老生奖金", "续读生顺期科数", "续读生跨期科数", "续读生科数","续读生奖金","总奖金"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;

        if (teacherCommissionDetailList!=null){
            for (TeacherCommissionDetail teacherCommissionDetail : teacherCommissionDetailList) {
                int cellNum = 0;

                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell  cell = row.createCell(cellNum++);
                cell.setCellValue(teacherCommissionDetail.getTeacherName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(teacherCommissionDetail.getBusTeamName());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(teacherCommissionDetail.getNewStudentNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(teacherCommissionDetail.getOldStudentNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(teacherCommissionDetail.getNewOldStudentNum());


                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(teacherCommissionDetail.getNewOldStudentAmount().doubleValue());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(teacherCommissionDetail.getSeqStudentNum());


                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(teacherCommissionDetail.getStepStudentNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(teacherCommissionDetail.getSeqStepStudentNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(teacherCommissionDetail.getSeqStepStudentAmount().doubleValue());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(teacherCommissionDetail.getTotalAmount().doubleValue());

            }
        }


        return excel;
    }

    @Override
    public List<ExternalCampusRegVo> findExternalCampusReg(List<Long> periodIds, ExternalRegQueryVo externalRegQueryVo) {
        if (Utils.checkListEmpty(periodIds) || externalRegQueryVo.getAreaTeamId()==null){
            return Collections.EMPTY_LIST;
        }
        PeriodSeqStepSituationVo periodSeqStepSituationVo=periodService.findPeriodSeqStepSituation(periodIds);

        List<Period> periodList=periodService.findByIds(periodIds);
        Map<String,ExternalCampusRegVo> map=new TreeMap<>();
        for (Period period:periodList){
            Long periodId=period.getPeriodId();
            List<ExternalRegDetail> onePeriodRegList=externalRegDetailService.findPeriodRegList(periodId,externalRegQueryVo,"periodId","studentId","campusNo","campusName","subjectId","gradeId");
            //  List<Long> externalStudentIds=BeanUtils.toList(onePeriodRegList,"studentId");

            List<Long> useSeqPeriodIds=periodSeqStepSituationVo.getSeqMap().get(periodId);
            List<Long> useStepPeriodIds=periodSeqStepSituationVo.getStepMap().get(periodId);
            List<Long> allPeriodIds=new ArrayList<>();
            allPeriodIds.addAll(useSeqPeriodIds);
            allPeriodIds.addAll(useStepPeriodIds);
            List<MergeStudentRegDetail> mergeStudentRegDetailList =mergeStudentRegDetailService.findListByAreaTeamIdPeriodIdsGradeId(externalRegQueryVo.getAreaTeamId(),allPeriodIds,31L,"studentId","periodId","classId","chargingStatus","regStatus","regId","gradeId","subjectId","segmentNo","lectureNum");
            mergeStudentRegDetailList=mergeStudentRegDetailService.filterRegByEffectiveLectureNum(mergeStudentRegDetailList,periodSeqStepSituationVo.getPeriodSegmentMap());
            mergeStudentRegDetailList=mergeStudentRegDetailService.filteRegByReportConfig(allPeriodIds,mergeStudentRegDetailList,ReportResourceEnum.初三校区续读.id);
            Map<Long, List<MergeStudentRegDetail>> studentRegDetailMap = BeanUtils.toGroup(mergeStudentRegDetailList, "studentId");
            Map<String, List<ExternalRegDetail>> campusPeriodMap = BeanUtils.toGroup(onePeriodRegList, "campusNo");
            Map<String,Integer> recordStudent=new HashMap<>();
            for (Map.Entry<String,List<ExternalRegDetail>> entry:campusPeriodMap.entrySet()){
                String campusNo=entry.getKey();
                String key=periodId+"_"+campusNo;
                ExternalCampusRegVo externalCampusRegVo=map.get(key);
                List<ExternalRegDetail> campusPeriodList=entry.getValue();
                if (externalCampusRegVo==null){
                    externalCampusRegVo=new ExternalCampusRegVo();
                    externalCampusRegVo.setPeriodId(periodId);
                    externalCampusRegVo.setPeriodName(period.getPeriodName());
                    externalCampusRegVo.setCampusNo(campusNo);
                    externalCampusRegVo.setNowBranchNum(campusPeriodList.size());
                }
                for (ExternalRegDetail externalRegDetail:campusPeriodList){
                    Long studentId=externalRegDetail.getStudentId();
                    String campusStudentKey=campusNo+"_"+studentId;
                    if (!recordStudent.containsKey(campusStudentKey)){
                        externalCampusRegVo.setNowPersonNum(externalCampusRegVo.getNowPersonNum()+1);
                        recordStudent.put(campusStudentKey,1);
                    }
                    List<MergeStudentRegDetail> oneMergeStudentRegDetailList =studentRegDetailMap.get(studentId);
                    externalCampusRegVo.setCampusName(externalRegDetail.getCampusName());
                    if (oneMergeStudentRegDetailList !=null){
                        for (MergeStudentRegDetail mergeStudentRegDetail : oneMergeStudentRegDetailList){
                            if (!mergeStudentRegDetail.getSubjectId().equals(externalRegDetail.getSubjectId())){
                                continue;
                            }
                            Long regPeriodId= mergeStudentRegDetail.getPeriodId();

                            if (useSeqPeriodIds.contains(regPeriodId)){
                                String regKey="seq"+"_"+campusNo+"_"+ mergeStudentRegDetail.getRegId();
                                if (!recordStudent.containsKey(regKey)){
                                    externalCampusRegVo.setSeqBranchNum(externalCampusRegVo.getSeqBranchNum()+1);
                                    recordStudent.put(regKey,1);
                                }
                                if (!recordStudent.containsKey(campusStudentKey+"_"+"4")){
                                    externalCampusRegVo.setSeqPersonNum(externalCampusRegVo.getSeqPersonNum()+1);
                                    recordStudent.put(campusStudentKey+"_"+"4",1);
                                }

                            }else if (useStepPeriodIds.contains(regPeriodId)){
                                String regKey="step"+"_"+campusNo+"_"+ mergeStudentRegDetail.getRegId();
                                if (!recordStudent.containsKey(regKey)){
                                    externalCampusRegVo.setStepBranchNum(externalCampusRegVo.getStepBranchNum()+1);
                                    recordStudent.put(regKey,1);
                                }

                                if (!recordStudent.containsKey(campusStudentKey+"_"+"5")){
                                    externalCampusRegVo.setStepPersonNum(externalCampusRegVo.getStepPersonNum()+1);
                                    recordStudent.put(campusStudentKey+"_"+"5",1);
                                }
                            }
                        }
                    }
                }
                externalCampusRegVo.setSeqRate(Utils.getPercent(externalCampusRegVo.getSeqBranchNum().toString(),externalCampusRegVo.getNowBranchNum().toString(),2));
                externalCampusRegVo.setStepRate(Utils.getPercent(externalCampusRegVo.getStepBranchNum().toString(),externalCampusRegVo.getNowBranchNum().toString(),2));
                map.put(key,externalCampusRegVo);
            }
        }
        Collection<ExternalCampusRegVo> externalCampusRegVoCollections=map.values();
        List<ExternalCampusRegVo> externalCampusRegVoList=new ArrayList<>(externalCampusRegVoCollections);
        return externalCampusRegVoList;
    }

    @Override
    public List<ExternalSeniorRegVo> findExternalSeniorReg(List<Long> periodIds, ExternalRegQueryVo externalRegQueryVo) {
        if (Utils.checkListEmpty(periodIds) || externalRegQueryVo.getAreaTeamId()==null){
            return Collections.EMPTY_LIST;
        }
        List<Period> periodList=periodService.findByIds(periodIds);
        PeriodSeqStepSituationVo periodSeqStepSituationVo=periodService.findPeriodSeqStepSituation(periodIds);

        Map<String,ExternalSeniorRegVo> map=new TreeMap<>();
        for (Period period:periodList){
            Long periodId=period.getPeriodId();
            List<ExternalRegDetail> onePeriodRegList=externalRegDetailService.findPeriodRegList(periodId,externalRegQueryVo,"periodId","studentId","campusNo","campusName","subjectId","gradeId","seniorNo","seniorName","seniorIdNo");
            //  List<Long> externalStudentIds=BeanUtils.toList(onePeriodRegList,"studentId");

            List<Long> useSeqPeriodIds=periodSeqStepSituationVo.getSeqMap().get(periodId);
            List<Long> useStepPeriodIds=periodSeqStepSituationVo.getStepMap().get(periodId);
            List<Long> allPeriodIds=new ArrayList<>();
            allPeriodIds.addAll(useSeqPeriodIds);
            allPeriodIds.addAll(useStepPeriodIds);
            List<MergeStudentRegDetail> mergeStudentRegDetailList =mergeStudentRegDetailService.findListByAreaTeamIdPeriodIdsGradeId(externalRegQueryVo.getAreaTeamId(),allPeriodIds,31L,"studentId","periodId","classId","chargingStatus","regStatus","regId","gradeId","subjectId","segmentNo","lectureNum");
            mergeStudentRegDetailList=mergeStudentRegDetailService.filterRegByEffectiveLectureNum(mergeStudentRegDetailList,periodSeqStepSituationVo.getPeriodSegmentMap());
            mergeStudentRegDetailList=mergeStudentRegDetailService.filteRegByReportConfig(allPeriodIds,mergeStudentRegDetailList,ReportResourceEnum.初三班主任续读.id);

            Map<Long, List<MergeStudentRegDetail>> studentRegDetailMap = BeanUtils.toGroup(mergeStudentRegDetailList, "studentId");
            Map<String, List<ExternalRegDetail>> campusPeriodMap = BeanUtils.toGroup(onePeriodRegList, "campusNo");

            Map<String,Integer> recordStudent=new HashMap<>();
            for (Map.Entry<String,List<ExternalRegDetail>> entry:campusPeriodMap.entrySet()){
                List<ExternalRegDetail> campusPeriodList=entry.getValue();
                String campusNo=entry.getKey();
                for (ExternalRegDetail externalRegDetail:campusPeriodList){
                    if (StringUtils.isEmpty(externalRegDetail.getSeniorIdNo())){
                        continue;
                    }
                    String key=periodId+"_"+campusNo+"_"+externalRegDetail.getSeniorIdNo();
                    ExternalSeniorRegVo externalSeniorRegVo=map.get(key);
                    Long studentId=externalRegDetail.getStudentId();
                    String seniorNo=externalRegDetail.getSeniorIdNo();
                    String campusSeniorStudentKey=campusNo+"_"+seniorNo+"_"+studentId;

                    if (externalSeniorRegVo==null){
                        externalSeniorRegVo=new ExternalSeniorRegVo();
                        externalSeniorRegVo.setPeriodId(periodId);
                        externalSeniorRegVo.setPeriodName(period.getPeriodName());
                        externalSeniorRegVo.setSeniorName(externalRegDetail.getSeniorName());
                        externalSeniorRegVo.setSeniorNo(externalRegDetail.getSeniorNo());
                        externalSeniorRegVo.setCampusName(externalRegDetail.getCampusName());
                        externalSeniorRegVo.setCampusNo(externalRegDetail.getCampusNo());
                    }
                    if (!recordStudent.containsKey(campusSeniorStudentKey)){
                        externalSeniorRegVo.setNowPersonNum(externalSeniorRegVo.getNowPersonNum()+1);
                        recordStudent.put(campusSeniorStudentKey,1);
                    }
                    externalSeniorRegVo.setNowBranchNum(externalSeniorRegVo.getNowBranchNum()+1);
                    List<MergeStudentRegDetail> oneMergeStudentRegDetailList =studentRegDetailMap.get(studentId);
                    externalSeniorRegVo.setCampusName(externalRegDetail.getCampusName());
                    if (oneMergeStudentRegDetailList !=null){
                        for (MergeStudentRegDetail mergeStudentRegDetail : oneMergeStudentRegDetailList){

                            if (!mergeStudentRegDetail.getSubjectId().equals(externalRegDetail.getSubjectId())){
                                continue;
                            }
                            Long regPeriodId= mergeStudentRegDetail.getPeriodId();

                            if (useSeqPeriodIds.contains(regPeriodId)){
                                String regKey="seq"+"_"+campusNo+"_"+seniorNo+"_"+ mergeStudentRegDetail.getRegId();
                                if (!recordStudent.containsKey(regKey)){
                                    externalSeniorRegVo.setSeqBranchNum(externalSeniorRegVo.getSeqBranchNum()+1);
                                    recordStudent.put(regKey,1);
                                }
                                if (!recordStudent.containsKey(campusSeniorStudentKey+"_"+"4")){
                                    externalSeniorRegVo.setSeqPersonNum(externalSeniorRegVo.getSeqPersonNum()+1);
                                    recordStudent.put(campusSeniorStudentKey+"_"+"4",1);
                                }
                            }else if (useStepPeriodIds.contains(regPeriodId)){
                                String regKey="step"+"_"+campusNo+"_"+seniorNo+"_"+ mergeStudentRegDetail.getRegId();
                                if (!recordStudent.containsKey(regKey)){
                                    externalSeniorRegVo.setStepBranchNum(externalSeniorRegVo.getStepBranchNum()+1);
                                    recordStudent.put(regKey,1);
                                }

                                if (!recordStudent.containsKey(campusSeniorStudentKey+"_"+"5")){
                                    externalSeniorRegVo.setStepPersonNum(externalSeniorRegVo.getStepPersonNum()+1);
                                    recordStudent.put(campusSeniorStudentKey+"_"+"5",1);
                                }
                            }
                        }
                    }
                    externalSeniorRegVo.setSeqRate(Utils.getPercent(externalSeniorRegVo.getSeqBranchNum().toString(),externalSeniorRegVo.getNowBranchNum().toString(),2));
                    externalSeniorRegVo.setStepRate(Utils.getPercent(externalSeniorRegVo.getStepBranchNum().toString(),externalSeniorRegVo.getNowBranchNum().toString(),2));
                    map.put(key,externalSeniorRegVo);
                }
            }

        }
        Collection<ExternalSeniorRegVo> externalSeniorRegVoCollection=map.values();
        List<ExternalSeniorRegVo> externalSeniorRegVoList=new ArrayList<>(externalSeniorRegVoCollection);
        return externalSeniorRegVoList;
    }

    @Override
    public SXSSFWorkbook exportExternalCampusReg(List<Long> periodIds, ExternalRegQueryVo externalRegQueryVo) {
        List<ExternalCampusRegVo> externalCampusRegVoList=this.findExternalCampusReg(periodIds,externalRegQueryVo);
        List<Period> periodList=periodService.findByIds(periodIds);
        Map<Long, Period> periodMap = BeanUtils.toMap(periodList, "periodId");
        Map<Long,BaseGrade> baseGradeMap=baseGradeService.findGradeMap();
        Map<Long,BaseSubject> baseSubjectMap=baseSubjectService.findSubjectMap();
        List<ExternalRegDetail> externalRegDetailList=externalRegDetailService.findPeriodsRegList(periodIds,externalRegQueryVo,"periodId","studentId","campusNo","campusName","subjectId","gradeId","className","level","seniorName");
        List<Long> studentIds = Utils.unique( BeanUtils.toList(externalRegDetailList, "studentId"));
        List<Student> student=studentService.findByIds(studentIds,"studentId","name","phoneNo");
        Map<Long, Student> studentMap = BeanUtils.toMap(student, "studentId");
        SXSSFWorkbook excel=externalCampusReg2excel(externalCampusRegVoList,periodMap,baseGradeMap,baseSubjectMap,studentMap,externalRegDetailList);
        externalReg2excel(excel,periodMap,baseGradeMap,baseSubjectMap,studentMap,externalRegDetailList);
        return excel;
    }

    @Override
    public SXSSFWorkbook exportExternalSeniorReg(List<Long> periodIds,  ExternalRegQueryVo externalRegQueryVo) {
        List<ExternalSeniorRegVo> externalSeniorRegVoList=this.findExternalSeniorReg(periodIds,externalRegQueryVo);

        return externalSeniorReg2excel(externalSeniorRegVoList);
    }

    public static SXSSFWorkbook externalCampusReg2excel(List<ExternalCampusRegVo> externalCampusRegVoList,Map<Long,Period> periodMap,Map<Long, BaseGrade> baseGradeMap, Map<Long,BaseSubject> baseSubjectMap, Map<Long,Student> studentMap, List<ExternalRegDetail> externalRegDetailList) {

        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("校区续读（初三）");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{ "校区", "期数", "本期人数","顺期人数", "跨期人数", "本期科数", "顺期科数", "顺期续读率", "跨期科数","跨期续读率"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;

        if (externalCampusRegVoList!=null){
            for (ExternalCampusRegVo externalCampusRegVo : externalCampusRegVoList) {
                int cellNum = 0;

                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell  cell = row.createCell(cellNum++);
                cell.setCellValue(externalCampusRegVo.getCampusName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(externalCampusRegVo.getPeriodName());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalCampusRegVo.getNowPersonNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalCampusRegVo.getSeqPersonNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalCampusRegVo.getStepPersonNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalCampusRegVo.getNowBranchNum());


                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalCampusRegVo.getSeqBranchNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(externalCampusRegVo.getSeqRate());


                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalCampusRegVo.getStepBranchNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalCampusRegVo.getStepRate());


            }
        }


        return excel;
    }

    public static SXSSFWorkbook externalReg2excel(SXSSFWorkbook excel, Map<Long,Period> periodMap,Map<Long, BaseGrade> baseGradeMap, Map<Long,BaseSubject> baseSubjectMap, Map<Long,Student> studentMap, List<ExternalRegDetail> externalRegDetailList) {

        SXSSFSheet sheet = excel.createSheet("学生报读信息");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{ "期数", "姓名","电话", "校区", "班级名称", "层级", "年级", "科目","班主任"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;

        if (externalRegDetailList!=null){
            for (ExternalRegDetail externalRegDetail : externalRegDetailList) {
                int cellNum = 0;

                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell  cell = row.createCell(cellNum++);
                cell.setCellValue(periodMap.get(externalRegDetail.getPeriodId()).getPeriodName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(studentMap.get(externalRegDetail.getStudentId()).getName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(studentMap.get(externalRegDetail.getStudentId()).getPhoneNo());

                cell = row.createCell(cellNum++);
                cell.setCellValue(externalRegDetail.getCampusName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(externalRegDetail.getClassName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(EnumUtils.getName(ClassLevelEnum.values(),externalRegDetail.getLevel()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(baseGradeMap.get(externalRegDetail.getGradeId()).getGradeName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(baseSubjectMap.get(externalRegDetail.getSubjectId()).getSubjectName());


                cell = row.createCell(cellNum++);
                cell.setCellValue(externalRegDetail.getSeniorName());

            }
        }


        return excel;
    }

    public static SXSSFWorkbook externalSeniorReg2excel(List<ExternalSeniorRegVo> externalSeniorRegVoList) {



        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("校区续读（初三）");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{ "校区", "期数","班主任", "本期人数","顺期人数", "跨期人数", "本期科数", "顺期科数", "顺期续读率", "跨期科数","跨期续读率"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;

        if (externalSeniorRegVoList!=null){
            for (ExternalSeniorRegVo externalSeniorRegVo : externalSeniorRegVoList) {
                int cellNum = 0;

                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell  cell = row.createCell(cellNum++);
                cell.setCellValue(externalSeniorRegVo.getCampusName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(externalSeniorRegVo.getPeriodName());

                cell = row.createCell(cellNum++);
                cell.setCellValue(externalSeniorRegVo.getSeniorName());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalSeniorRegVo.getNowPersonNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalSeniorRegVo.getSeqPersonNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalSeniorRegVo.getStepPersonNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalSeniorRegVo.getNowBranchNum());


                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalSeniorRegVo.getSeqBranchNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(externalSeniorRegVo.getSeqRate());


                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalSeniorRegVo.getStepBranchNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(externalSeniorRegVo.getStepRate());
            }
        }


        return excel;
    }

    @Override
    public Page<ClassRegDetailVo> findClassRegDetailPage(CourseClassQueryVo courseClassQueryVo,DataPermission dataPermission, int pageNo, int pageSize) {
        Page<CourseClass> courseClassPage=courseClassService.findCourseClassByQueryForPage(courseClassQueryVo,dataPermission,pageNo,pageSize);

        Page<ClassRegDetailVo> classRegDetailVoPage=Utils.newPage(courseClassPage);

        List<CourseClass> courseClassList=courseClassPage.getRecords();
        if (courseClassList==null && courseClassList.size()<=0){
            return classRegDetailVoPage;
        }
        List<Long> classIds=BeanUtils.toList(courseClassList,"classId");

        List<Long> teacherIds=BeanUtils.toList(courseClassList,"teacherId");

        List<Teacher> teacherList=teacherService.findByIds(teacherIds,"teacherId","teacherName","jobNature");
        Map<Long,Teacher> teacherMap=BeanUtils.toMap(teacherList,"teacherId");

        List<RegDetailByClass> regDetailByClassList=mergeStudentRegDetailService.findClassRegDetail(classIds);
        Map<Long,List<RegDetailByClass>> regMap=BeanUtils.toGroup(regDetailByClassList,"classId");
        List<ClassRegDetailVo> classRegDetailVoList=new ArrayList<>(courseClassList.size());
        for (CourseClass courseClass:courseClassList){
            ClassRegDetailVo classRegDetailVo=new ClassRegDetailVo();
            BeanUtils.copyProperties(classRegDetailVo,courseClass);
            Teacher teacher=teacherMap.get(courseClass.getTeacherId());
            if (teacher!=null){
                classRegDetailVo.setTeacherName(teacher.getTeacherName());
                classRegDetailVo.setJobNature(teacher.getJobNature().intValue());
            }

            List<RegDetailByClass> oneClassReg=regMap.get(courseClass.getClassId());
            if (oneClassReg!=null){
                for (RegDetailByClass regDetailByClass:oneClassReg){
                    if (regDetailByClass.getStudentState()==0){
                        classRegDetailVo.setNewStudentNum(classRegDetailVo.getNewStudentNum()+regDetailByClass.getRegNum());
                        classRegDetailVo.setNewStudentAmount(classRegDetailVo.getNewStudentAmount().add(regDetailByClass.getRealAmount()));
                    }else if (regDetailByClass.getStudentState()==1){
                        classRegDetailVo.setOldStudentNum(classRegDetailVo.getOldStudentNum()+regDetailByClass.getRegNum());
                        classRegDetailVo.setOldStudentAmount(classRegDetailVo.getOldStudentAmount().add(regDetailByClass.getRealAmount()));
                    }else if (regDetailByClass.getStudentState()==2){
                        classRegDetailVo.setSeqOrStepStudentNum(classRegDetailVo.getSeqOrStepStudentNum()+regDetailByClass.getRegNum());
                        classRegDetailVo.setSeqOrStepStudentAmount(classRegDetailVo.getSeqOrStepStudentAmount().add(regDetailByClass.getRealAmount()));
                    }
                }
            }
            classRegDetailVo.setTotalAmount(classRegDetailVo.getNewStudentAmount().add(classRegDetailVo.getOldStudentAmount()).add(classRegDetailVo.getSeqOrStepStudentAmount()));


            classRegDetailVoList.add(classRegDetailVo);
        }
        classRegDetailVoPage.setRecords(classRegDetailVoList);
        return classRegDetailVoPage;
    }

    @Override
    public SXSSFWorkbook exportClassRegDetail(CourseClassQueryVo courseClassQueryVo,DataPermission dataPermission) {
        Page<ClassRegDetailVo> classRegDetailVoPage=this.findClassRegDetailPage(courseClassQueryVo,dataPermission,1,50000);

        return classRegDetail2excel(classRegDetailVoPage.getRecords());
    }
    public static SXSSFWorkbook classRegDetail2excel(List<ClassRegDetailVo> classRegDetailVoList) {

        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("班别明细");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{ "区域", "业务组", "班级编号","班级名称", "期数", "段次", "年级", "科目", "班型","校区","主讲教师","任教性质","班主任","开课日期","上课时间","结课日期","学费","已报人数","新生人数","老生人数","续读生人数","已缴金额","新生金额","老生金额","续读生金额"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;

        if (classRegDetailVoList!=null){
            for (ClassRegDetailVo classRegDetailVo : classRegDetailVoList) {
                int cellNum = 0;

                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell  cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classRegDetailVo.getAreaTeamName()));


                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classRegDetailVo.getBusTeamName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classRegDetailVo.getClassNo()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classRegDetailVo.getClassName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classRegDetailVo.getPeriodName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getSegmentNo()==null?"":classRegDetailVo.getSegmentNo().toString());

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classRegDetailVo.getGradeName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classRegDetailVo.getSubjectName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getLevel()==null?"":EnumUtils.getName(ClassLevelEnum.values(),classRegDetailVo.getLevel()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classRegDetailVo.getCampusName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classRegDetailVo.getTeacherName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getJobNature()==null?"":EnumUtils.getName(JobNatureEnum.values(),classRegDetailVo.getJobNature()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classRegDetailVo.getSeniorName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getStartCourseTime()==null?"":Utils.formatDate(classRegDetailVo.getStartCourseTime(),"yyyy-MM-dd"));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(classRegDetailVo.getStudyingTime()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getEndCourseTime()==null?"":Utils.formatDate(classRegDetailVo.getEndCourseTime(),"yyyy-MM-dd"));

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getStudyingFee()==null?0D:classRegDetailVo.getStudyingFee().doubleValue());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getRegAmount());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getNewStudentNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getOldStudentNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getSeqOrStepStudentNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getTotalAmount()==null?0d:classRegDetailVo.getTotalAmount().doubleValue());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getNewStudentAmount().doubleValue());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getOldStudentAmount().doubleValue());

                cell = row.createCell(cellNum++);
                cell.setCellValue(classRegDetailVo.getSeqOrStepStudentAmount().doubleValue());

            }
        }
        return excel;
    }

    @Override
    public Page<AcademicAdvisorDataVo> findAcademicAdvisorData(Long areaTeamId,TeacherQueryVo teacherQueryVo, Date startDate, Date endDate,int pageNo,int pageSize) {
        if (startDate==null || endDate==null){
            throw new BusException("开始结束时间必选");
        }
        if (areaTeamId==null){
            throw new BusException("区域必选");
        }
        String startYear=Utils.formatDate(startDate,"yyyy-MM-dd").substring(0,4);
        String endYear=Utils.formatDate(endDate,"yyyy-MM-dd").substring(0,4);
        if (!startYear.equals(endYear)){
            throw new BusException("开始结束年份必须在同一年份");
        }
        List<Period> periodList=periodService.findByYearAndAreaTeamId(areaTeamId,startYear);

        List<Long> winterSpringPeriodIds=new ArrayList<>(3);
        List<Long> summerAutumnPeriodIds=new ArrayList<>(3);
        Period winterPeriod=null;
        Period springPeriod=null;
        Period summerPeriod=null;
        Period autumnPeriod=null;
        for (Period period:periodList){
            String periodName=period.getPeriodName();
            Long periodId=period.getPeriodId();
            if (periodName.contains("寒") ){
                winterPeriod=period;
                winterSpringPeriodIds.add(periodId);
            }else if( periodName.contains("春")){
                springPeriod=period;
                winterSpringPeriodIds.add(periodId);
            }else if (periodName.contains("暑")){
                summerPeriod=period;
                summerAutumnPeriodIds.add(periodId);
            }else if( periodName.contains("秋")){
                autumnPeriod=period;
                summerAutumnPeriodIds.add(periodId);
            }
        }

        if (winterPeriod ==null || springPeriod==null || summerPeriod==null || autumnPeriod==null){
            throw new BusException("查询期数出错");
        }

        Map<String,Integer> record=new HashMap<>();// key=teacherId+"_"+studentId;
        Map<String,Integer> recordRegDetail=new HashMap<>();//key=teacherId+"_"+regId;
        Page<Teacher> teacherPage=teacherService.findTeacherByBusTeamListForPage(teacherQueryVo,null,pageNo,pageSize);
        Page<AcademicAdvisorDataVo> academicAdvisorDataVoPage=Utils.newPage(teacherPage);
        List<Teacher> teacherList = teacherPage.getRecords();
        if (teacherList==null || teacherList.size()<=0){
            return academicAdvisorDataVoPage;
        }
        List<String> teacherIdNos=BeanUtils.toList(teacherList,"idNo");
        List<Long> teacherIds=BeanUtils.toList(teacherList,"teacherId");
        List<AcademicAdvisorDataVo> academicAdvisorDataVoList=new ArrayList<>(teacherList.size());
        PeriodQueryRegVo periodQueryRegVo=new PeriodQueryRegVo();
        periodQueryRegVo.setStartPayTime(startDate);
        periodQueryRegVo.setEndPayTime(endDate);
        periodQueryRegVo.setRegStatus(0);
        periodQueryRegVo.setChargingStatus(2);
        periodQueryRegVo.setAreaTeamId(areaTeamId);
        periodQueryRegVo.setPeriodIds(summerAutumnPeriodIds);
        periodQueryRegVo.setGradeId(31L);
        List<MergeStudentRegDetail> mergeStudentRegDetailList =null;
        List<ExternalRegDetail> externalRegDetailList=null;
        if(teacherList.size()<=10){
            externalRegDetailList=externalRegDetailService.findBySeniorIdNosPeriodIdsGradeId(areaTeamId,winterSpringPeriodIds,teacherIdNos,23L,"studentId","periodId","seniorName","seniorIdNo");
            List<Long> studentIds=BeanUtils.toList(externalRegDetailList,"studentId");
            studentIds=Utils.removeDuplicate(studentIds);
            mergeStudentRegDetailList =mergeStudentRegDetailService.findByStudentIdsPeriodIds(studentIds,summerAutumnPeriodIds,periodQueryRegVo,studentRegDetailColumns);
            mergeStudentRegDetailList=new ArrayList<>(mergeStudentRegDetailList);
            List<MergeStudentRegDetail> tempList=mergeStudentRegDetailService.findByCounselorIdsPeriodIdsStates(teacherIds,summerAutumnPeriodIds,null,periodQueryRegVo,studentRegDetailColumns);
            if (mergeStudentRegDetailList !=null && tempList!=null){
                mergeStudentRegDetailList.addAll(tempList);
                List<Long> externalStudentIds = BeanUtils.toList(tempList, "studentId");

                List<ExternalRegDetail> tempExternalList=externalRegDetailService.findByStudentIdsPeriodIdsGradeId(externalStudentIds,winterSpringPeriodIds,23L,"studentId","periodId","seniorName","seniorIdNo");
                if (externalRegDetailList!=null && tempExternalList!=null){
                    externalRegDetailList.addAll(tempExternalList);
                }else {
                    externalRegDetailList=tempExternalList;
                }
            }else {
                mergeStudentRegDetailList =tempList;
            }
        }else {
            mergeStudentRegDetailList =mergeStudentRegDetailService.findByAreaTeamIdPeriodIds(areaTeamId,summerAutumnPeriodIds,periodQueryRegVo,studentRegDetailColumns);
            externalRegDetailList=externalRegDetailService.findByAreaTeamIdPeriodIdsGradeId(areaTeamId,winterSpringPeriodIds,23L,"studentId","periodId","seniorName","seniorIdNo");
        }
        Map<String,List<ExternalRegDetail>> studentPeriodExternalMap=new HashMap<>();//记录在外部系统报名学生，key= studentId_periodId
        Map<String,List<ExternalRegDetail>> seniorIdNoExternalMap=new HashMap<>();//记录每个班主任身份证对应的外部学生报名信息。
        for (ExternalRegDetail externalRegDetail:externalRegDetailList){
            Long studentId=externalRegDetail.getStudentId();
            Long periodId=externalRegDetail.getPeriodId();
            String key=externalRegDetail.getSeniorIdNo()+"_"+studentId+"_"+periodId;
            List<ExternalRegDetail> studentPeriodExternalList=studentPeriodExternalMap.get(key);
            if (studentPeriodExternalList==null){
                studentPeriodExternalList=new ArrayList<>();
                studentPeriodExternalMap.put(key,studentPeriodExternalList);
            }
            studentPeriodExternalList.add(externalRegDetail);
            String seniorIdNo=externalRegDetail.getSeniorIdNo();
            if (StringUtils.isNotEmpty(seniorIdNo)){
                List<ExternalRegDetail> seniorIdNoExternalList=seniorIdNoExternalMap.get(seniorIdNo);
                if (seniorIdNoExternalList==null){
                    seniorIdNoExternalList=new ArrayList<>();
                    seniorIdNoExternalMap.put(seniorIdNo,seniorIdNoExternalList);
                }
                seniorIdNoExternalList.add(externalRegDetail);
            }
        }

        List<PeriodSegment> periodSegmentList=periodSegmentService.findByPeriodSegmentListByPeriodIds(summerAutumnPeriodIds);
        Map<Long,Map<Integer,PeriodSegment>> periodSegmentMap=periodSegmentService.periodSegmentToMapGroup(periodSegmentList);

        mergeStudentRegDetailList=mergeStudentRegDetailService.filterRegByEffectiveLectureNum(mergeStudentRegDetailList,periodSegmentMap);
        mergeStudentRegDetailList=mergeStudentRegDetailService.filteRegByReportConfig(summerAutumnPeriodIds,mergeStudentRegDetailList,ReportResourceEnum.班主任推广数据.id);

        Map<String,List<MergeStudentRegDetail>> studentPeriodRegMap=new HashMap<>();//记录在本系统报名学生，key= studentId_periodId
        Map<Long,List<MergeStudentRegDetail>> oneStudentRegMap=new HashMap<>();//记录在本系统报名续读生，key= studentId
        Map<Long,List<MergeStudentRegDetail>> counselorStudentRegMap=new HashMap<>();
        for (MergeStudentRegDetail mergeStudentRegDetail : mergeStudentRegDetailList){
            /*满足有效讲次*/
            Long studentId= mergeStudentRegDetail.getStudentId();
            Long periodId= mergeStudentRegDetail.getPeriodId();
            Long counselorId= mergeStudentRegDetail.getCounselorId();
            Long gradeId= mergeStudentRegDetail.getGradeId();
            Integer studentState= mergeStudentRegDetail.getStudentState();
            if (counselorId!=null){
                List<MergeStudentRegDetail> counselorStudentRegList=counselorStudentRegMap.get(counselorId);
                if (counselorStudentRegList==null){
                    counselorStudentRegList=new ArrayList<>();
                    counselorStudentRegMap.put(counselorId,counselorStudentRegList);
                }
                counselorStudentRegList.add(mergeStudentRegDetail);
            }
            if (gradeId==31L && studentState==2){
                List<MergeStudentRegDetail> studentRegList=oneStudentRegMap.get(studentId);
                if (studentRegList==null){
                    studentRegList=new ArrayList<>();
                    oneStudentRegMap.put(studentId,studentRegList);
                }
                studentRegList.add(mergeStudentRegDetail);
            }

            String key=studentId+"_"+periodId;
            List<MergeStudentRegDetail> studentPeriodRegList=studentPeriodRegMap.get(key);
            if (studentPeriodRegList==null){
                studentPeriodRegList=new ArrayList<>();
                studentPeriodRegMap.put(key,studentPeriodRegList);
            }
            studentPeriodRegList.add(mergeStudentRegDetail);
        }

        for (Teacher teacher:teacherList){
            List<Long> unContinueStudentIdList=new ArrayList<>();
            Map<String,AcademicAdvisorStudentVo>  academicAdvisorStudentVoMap=new HashMap<>();//key:studentId_studentState;
            Long teacherId=teacher.getTeacherId();
            String teacherName=teacher.getTeacherName();
            String phoneNo=teacher.getPhoneNo();
            String idNo=teacher.getIdNo();

            AcademicAdvisorDataVo academicAdvisorDataVo=new AcademicAdvisorDataVo();
            academicAdvisorDataVo.setAreaTeamId(areaTeamId);
            academicAdvisorDataVo.setTeacherId(teacherId);
            academicAdvisorDataVo.setTeacherName(teacherName);
            academicAdvisorDataVo.setPhoneNo(phoneNo);

            List<ExternalRegDetail> seniorExternalRegList=seniorIdNoExternalMap.get(idNo);
            if (seniorExternalRegList!=null){
                List<Long> studentIds=Utils.removeDuplicate(BeanUtils.toList(seniorExternalRegList,"studentId"));
                for (Long studentId :studentIds){
                    List<MergeStudentRegDetail> oneMergeStudentRegDetailList =oneStudentRegMap.get(studentId);
                    if (oneMergeStudentRegDetailList !=null){
                        for (MergeStudentRegDetail mergeStudentRegDetail : oneMergeStudentRegDetailList){
                            Long periodId= mergeStudentRegDetail.getPeriodId();
                            Long regId= mergeStudentRegDetail.getRegId();
                            Integer studentState= mergeStudentRegDetail.getStudentState();
                            String key=teacherId+"_"+studentId;
                            //春季在读 算给班主任
                            if (studentPeriodExternalMap.containsKey(idNo+"_"+studentId+"_"+springPeriod.getPeriodId())){
                                if (!record.containsKey(key)){
                                    academicAdvisorDataVo.setSeqStepPersonNum(academicAdvisorDataVo.getSeqStepPersonNum()+1);
                                    record.put(key,1);
                                }
                                String regKey=teacherId+"_"+regId;
                                if (!recordRegDetail.containsKey(regKey)){
                                    recordRegDetail.put(regKey,1);
                                    AcademicAdvisorStudentVo academicAdvisorStudentVo=academicAdvisorStudentVoMap.get(studentId+"_"+studentState);
                                    if (academicAdvisorStudentVo==null){
                                        academicAdvisorStudentVo=new AcademicAdvisorStudentVo();
                                        academicAdvisorStudentVo.setStudentId(studentId);
                                        academicAdvisorStudentVo.setStudentName(mergeStudentRegDetail.getStudentName());
                                        academicAdvisorStudentVo.setStudentPhoneNo(mergeStudentRegDetail.getStudentPhoneNo());
                                        academicAdvisorStudentVo.setStudentState(studentState);
                                        academicAdvisorStudentVoMap.put(studentId+"_"+studentState,academicAdvisorStudentVo);
                                    }
                                    academicAdvisorStudentVo.setRegDetail((StringUtils.isEmpty(academicAdvisorStudentVo.getRegDetail())?"":(academicAdvisorStudentVo.getRegDetail()+","))+ mergeStudentRegDetail.getBusTeamName()+"/"+ mergeStudentRegDetail.getGradeName()+"/"+ mergeStudentRegDetail.getClassName());
                                }
                            }else {
                                /*未激活春季必须在读*/
                                if (studentPeriodExternalMap.containsKey(idNo+"_"+studentId+"_"+springPeriod.getPeriodId())){
                                    unContinueStudentIdList.add(studentId);
                                }

                            }
                        }
                    }else {
                        if (studentPeriodExternalMap.containsKey(idNo+"_"+studentId+"_"+springPeriod.getPeriodId())){
                            unContinueStudentIdList.add(studentId);
                        }
                    }
                }
            }
            List<MergeStudentRegDetail> counselorMergeStudentRegDetailList =counselorStudentRegMap.get(teacherId);
            if (counselorMergeStudentRegDetailList !=null){
                for (MergeStudentRegDetail mergeStudentRegDetail : counselorMergeStudentRegDetailList){
                    Integer studentState= mergeStudentRegDetail.getStudentState();
                    Long periodId= mergeStudentRegDetail.getPeriodId();
                    Long studentId= mergeStudentRegDetail.getStudentId();
                    Long regId= mergeStudentRegDetail.getRegId();
                    String key=teacherId+"_"+studentId;
                    if (studentState==0 ){
                        if (!record.containsKey(key)){
                            academicAdvisorDataVo.setNewPersonNum(academicAdvisorDataVo.getNewPersonNum()+1);
                            record.put(key,1);
                        }
                        String regKey=teacherId+"_"+regId;
                        if (!recordRegDetail.containsKey(regKey)){
                            recordRegDetail.put(regKey,1);
                            AcademicAdvisorStudentVo academicAdvisorStudentVo=academicAdvisorStudentVoMap.get(studentId+"_"+studentState);
                            if (academicAdvisorStudentVo==null){
                                academicAdvisorStudentVo=new AcademicAdvisorStudentVo();
                                academicAdvisorStudentVo.setStudentId(studentId);
                                academicAdvisorStudentVo.setStudentName(mergeStudentRegDetail.getStudentName());
                                academicAdvisorStudentVo.setStudentPhoneNo(mergeStudentRegDetail.getStudentPhoneNo());
                                academicAdvisorStudentVo.setStudentState(studentState);
                                academicAdvisorStudentVoMap.put(studentId+"_"+studentState,academicAdvisorStudentVo);
                            }
                            academicAdvisorStudentVo.setRegDetail((StringUtils.isEmpty(academicAdvisorStudentVo.getRegDetail())?"":(academicAdvisorStudentVo.getRegDetail()+","))+ mergeStudentRegDetail.getBusTeamName()+"/"+ mergeStudentRegDetail.getGradeName()+"/"+ mergeStudentRegDetail.getClassName());
                        }
                    }else if (studentState==1 ){
                        if (!record.containsKey(key)){
                            academicAdvisorDataVo.setOldPersonNum(academicAdvisorDataVo.getOldPersonNum()+1);
                            record.put(key,1);
                        }
                        String regKey=teacherId+"_"+regId;
                        if (!recordRegDetail.containsKey(regKey)){
                            recordRegDetail.put(regKey,1);
                            AcademicAdvisorStudentVo academicAdvisorStudentVo=academicAdvisorStudentVoMap.get(studentId+"_"+studentState);
                            if (academicAdvisorStudentVo==null){
                                academicAdvisorStudentVo=new AcademicAdvisorStudentVo();
                                academicAdvisorStudentVo.setStudentId(studentId);
                                academicAdvisorStudentVo.setStudentName(mergeStudentRegDetail.getStudentName());
                                academicAdvisorStudentVo.setStudentPhoneNo(mergeStudentRegDetail.getStudentPhoneNo());
                                academicAdvisorStudentVo.setStudentState(studentState);
                                academicAdvisorStudentVoMap.put(studentId+"_"+studentState,academicAdvisorStudentVo);
                            }
                            academicAdvisorStudentVo.setRegDetail((StringUtils.isEmpty(academicAdvisorStudentVo.getRegDetail())?"":(academicAdvisorStudentVo.getRegDetail()+","))+ mergeStudentRegDetail.getBusTeamName()+"/"+ mergeStudentRegDetail.getGradeName()+"/"+ mergeStudentRegDetail.getClassName());
                        }


                    }else if (studentState==2 ){
                        /*报读的是暑假 并且 春季不在读*/
                        if (periodId.equals(summerPeriod.getPeriodId()) && !studentPeriodExternalMap.containsKey(idNo+"_"+studentId+"_"+springPeriod.getPeriodId()) ){
                            if (!record.containsKey(key)){
                                academicAdvisorDataVo.setSeqStepPersonNum(academicAdvisorDataVo.getSeqStepPersonNum()+1);
                                record.put(key,1);
                            }
                            String regKey=teacherId+"_"+regId;
                            if (!recordRegDetail.containsKey(regKey)){
                                recordRegDetail.put(regKey,1);
                                AcademicAdvisorStudentVo academicAdvisorStudentVo=academicAdvisorStudentVoMap.get(studentId+"_"+studentState);
                                if (academicAdvisorStudentVo==null){
                                    academicAdvisorStudentVo=new AcademicAdvisorStudentVo();
                                    academicAdvisorStudentVo.setStudentId(studentId);
                                    academicAdvisorStudentVo.setStudentName(mergeStudentRegDetail.getStudentName());
                                    academicAdvisorStudentVo.setStudentPhoneNo(mergeStudentRegDetail.getStudentPhoneNo());
                                    academicAdvisorStudentVo.setStudentState(studentState);
                                    academicAdvisorStudentVoMap.put(studentId+"_"+studentState,academicAdvisorStudentVo);
                                }
                                academicAdvisorStudentVo.setRegDetail((StringUtils.isEmpty(academicAdvisorStudentVo.getRegDetail())?"":(academicAdvisorStudentVo.getRegDetail()+","))+ mergeStudentRegDetail.getBusTeamName()+"/"+ mergeStudentRegDetail.getGradeName()+"/"+ mergeStudentRegDetail.getClassName());
                            }
                        }
                    }
                }
            }
            Collection<AcademicAdvisorStudentVo> academicAdvisorStudentVoCollection=academicAdvisorStudentVoMap.values();
            List<AcademicAdvisorStudentVo> academicAdvisorStudentVoList=new ArrayList<>(academicAdvisorStudentVoCollection);
            if(teacherList.size()==1){
                List<Long> haveStudentIds=BeanUtils.toList(academicAdvisorStudentVoList,"studentId");
                unContinueStudentIdList=Utils.removeDuplicate(unContinueStudentIdList);
                unContinueStudentIdList.removeAll(haveStudentIds);
                if (unContinueStudentIdList.size()>0){
                    List<Student> studentList=studentService.findByIds(unContinueStudentIdList,"studentId","name","phoneNo");
                    academicAdvisorDataVo.setUnContinueStudentList(studentList);
                }
            }
            academicAdvisorDataVo.setAcademicAdvisorStudentVoList(academicAdvisorStudentVoList);
            academicAdvisorDataVoList.add(academicAdvisorDataVo);
        }
        academicAdvisorDataVoPage.setRecords(academicAdvisorDataVoList);
        return academicAdvisorDataVoPage;
    }

    @Override
    public SXSSFWorkbook exportAcademicAdvisorData(Long areaTeamId, TeacherQueryVo teacherQueryVo, Date startDate, Date endDate) {
        Page<AcademicAdvisorDataVo> academicAdvisorDataPage = this.findAcademicAdvisorData(areaTeamId, teacherQueryVo, startDate, endDate, 1, 2000);

        return academicAdvisorData2excel(academicAdvisorDataPage.getRecords());
    }

    public static SXSSFWorkbook academicAdvisorData2excel(List<AcademicAdvisorDataVo> academicAdvisorDataVoList) {

        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("推广数据");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{ "学习顾问","手机号码", "新生人数", "老生人数","续读人数"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }

        SXSSFSheet sheetDetail = excel.createSheet("推广数据详情");
        SXSSFRow firstDetailRow = sheetDetail.createRow(0);
        String[] detailTitles = new String[]{ "学习顾问","手机号码", "学生姓名", "学生电话","生源类型","报读情况"};

        for (int i = 0; i < detailTitles.length; i++) {
            firstDetailRow.createCell(i).setCellValue(detailTitles[i]);
        }


        int rowNum = 1;
        int detailRowNum=1;
        if (academicAdvisorDataVoList!=null){
            for (AcademicAdvisorDataVo academicAdvisorDataVo : academicAdvisorDataVoList) {
                int cellNum = 0;

                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell  cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(academicAdvisorDataVo.getTeacherName()));


                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(academicAdvisorDataVo.getPhoneNo()));

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(academicAdvisorDataVo.getNewPersonNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(academicAdvisorDataVo.getOldPersonNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(academicAdvisorDataVo.getSeqStepPersonNum());


                List<AcademicAdvisorStudentVo> academicAdvisorStudentVoList=academicAdvisorDataVo.getAcademicAdvisorStudentVoList();
                if (academicAdvisorStudentVoList!=null){
                    for (AcademicAdvisorStudentVo academicAdvisorStudentVo:academicAdvisorStudentVoList){
                        cellNum = 0;

                        SXSSFRow detailRow = sheetDetail.createRow(detailRowNum++);

                        SXSSFCell  detailCell = detailRow.createCell(cellNum++);
                        detailCell.setCellValue(StringUtils.defaultString(academicAdvisorDataVo.getTeacherName()));

                        detailCell = detailRow.createCell(cellNum++);
                        detailCell.setCellValue(StringUtils.defaultString(academicAdvisorDataVo.getPhoneNo()));

                        detailCell = detailRow.createCell(cellNum++);
                        detailCell.setCellValue(StringUtils.defaultString(academicAdvisorStudentVo.getStudentName()));

                        detailCell = detailRow.createCell(cellNum++);
                        detailCell.setCellValue(StringUtils.defaultString(academicAdvisorStudentVo.getStudentPhoneNo()));

                        detailCell = detailRow.createCell(cellNum++);
                        detailCell.setCellValue(academicAdvisorStudentVo.getStudentState()==null?"":academicAdvisorStudentVo.getStudentState()==0?"新生":academicAdvisorStudentVo.getStudentState()==1?"老生":"续读生");

                        detailCell = detailRow.createCell(cellNum++);
                        detailCell.setCellValue(StringUtils.defaultString(academicAdvisorStudentVo.getRegDetail()));
                    }
                }

            }
        }
        return excel;
    }


    @Override
    public OnlineList findOnlineList(Long areaTeamId,List<Long> periodIds, PeriodQueryRegVo periodQueryRegVo) {
        if (areaTeamId==null || Utils.checkListEmpty(periodIds)){
            throw new BusException("区域和期数必传");
        }
        AreaTeam areaTeam=areaTeamService.findById(areaTeamId);
        List<BaseGrade> baseGradeList=baseGradeService.findAllFromCache();
        Map<Long,BaseGrade> baseGradeMap=BeanUtils.toMap(baseGradeList,"gradeId");
        List<BaseSubject> baseSubjectList=baseSubjectService.findAllFromCache();
        Map<Long,BaseSubject> baseSubjectMap=BeanUtils.toMap(baseSubjectList,"subjectId");
        List<BusTeam> busTeamList=busTeamService.findBusTeamByAreaTeamIds(Arrays.asList(areaTeamId));
        Map<Long,BusTeam> busTeamMap=BeanUtils.toMap(busTeamList,"busTeamId");
        List<MergeStudentRegDetail> mergeStudentRegDetailList =mergeStudentRegDetailService.findByAreaTeamIdPeriodIds(areaTeamId,periodIds,periodQueryRegVo,"regId","busTeamId","gradeId","subjectId","regFrom");

        OnlineList onlineList=new OnlineList();
        Map<Long,OnlineData> busTeamOnlineDataMap=new HashMap<>();
        Map<Long,OnlineData> gradeOnlineDataMap=new HashMap<>(20);
        Map<Long,OnlineData> subjectOnlineDataMap=new HashMap<>(20);
        for (MergeStudentRegDetail mergeStudentRegDetail : mergeStudentRegDetailList){
            Long busTeamId= mergeStudentRegDetail.getBusTeamId();
            BusTeam busTeam=busTeamMap.get(busTeamId);
            if (busTeam==null){
                continue;
            }
            Long gradeId= mergeStudentRegDetail.getGradeId();
            Long subjectId= mergeStudentRegDetail.getSubjectId();
            Integer regFrom= mergeStudentRegDetail.getRegFrom();
            OnlineData busTeamOnlineData=busTeamOnlineDataMap.get(busTeamId);
            if (busTeamOnlineData==null){
                busTeamOnlineData=new OnlineData();
                busTeamOnlineData.setAreaTeamId(areaTeamId);
                busTeamOnlineData.setAreaTeamName(areaTeam.getName());
                busTeamOnlineData.setBusTeamId(busTeamId);
                busTeamOnlineData.setBusTeamName(busTeamMap.get(busTeamId)==null?"":busTeamMap.get(busTeamId).getName());
                busTeamOnlineDataMap.put(busTeamId,busTeamOnlineData);
            }
            busTeamOnlineData.setTotalBranchNum(busTeamOnlineData.getTotalBranchNum()+1);

            OnlineData gradeOnlineData=gradeOnlineDataMap.get(gradeId);
            if (gradeOnlineData==null){
                gradeOnlineData=new OnlineData();
                gradeOnlineData.setAreaTeamId(areaTeamId);
                gradeOnlineData.setAreaTeamName(areaTeam.getName());
                gradeOnlineData.setGradeId(gradeId);
                gradeOnlineData.setGradeName(baseGradeMap.get(gradeId)==null?"":baseGradeMap.get(gradeId).getGradeName());
                gradeOnlineDataMap.put(gradeId,gradeOnlineData);
            }
            gradeOnlineData.setTotalBranchNum(gradeOnlineData.getTotalBranchNum()+1);

            OnlineData subjectOnlineData=subjectOnlineDataMap.get(subjectId);
            if (subjectOnlineData==null){
                subjectOnlineData=new OnlineData();
                subjectOnlineData.setAreaTeamId(areaTeamId);
                subjectOnlineData.setAreaTeamName(areaTeam.getName());
                subjectOnlineData.setSubjectId(subjectId);
                subjectOnlineData.setSubjectName(baseSubjectMap.get(subjectId)==null?"":baseSubjectMap.get(subjectId).getSubjectName());
                subjectOnlineDataMap.put(subjectId,subjectOnlineData);
            }
            subjectOnlineData.setTotalBranchNum(subjectOnlineData.getTotalBranchNum()+1);
            if (regFrom!=null && regFrom==1){
                busTeamOnlineData.setOnlineBranchNum(busTeamOnlineData.getOnlineBranchNum()+1);
                gradeOnlineData.setOnlineBranchNum(gradeOnlineData.getOnlineBranchNum()+1);
                subjectOnlineData.setOnlineBranchNum(subjectOnlineData.getOnlineBranchNum()+1);
            }
        }
        Collection<OnlineData> busTeamOnlineDataCollection=busTeamOnlineDataMap.values();
        List<OnlineData> busTeamOnlineDataList=new ArrayList<>(busTeamOnlineDataCollection);
        Collections.sort(busTeamOnlineDataList, new Comparator<OnlineData>() {
            @Override
            public int compare(OnlineData o1, OnlineData o2) {
                return o2.getOnlineBranchNum().compareTo(o1.getOnlineBranchNum());
            }
        });
        onlineList.setBusTeamOnlineData(busTeamOnlineDataList);


        Collection<OnlineData> gradeOnlineDataCollection=gradeOnlineDataMap.values();
        List<OnlineData> gradeOnlineDataList=new ArrayList<>(gradeOnlineDataCollection);
        Collections.sort(gradeOnlineDataList, new Comparator<OnlineData>() {
            @Override
            public int compare(OnlineData o1, OnlineData o2) {
                return o2.getOnlineBranchNum().compareTo(o1.getOnlineBranchNum());
            }
        });
        onlineList.setGradeOnlineData(gradeOnlineDataList);

        Collection<OnlineData> subjectOnlineDataCollection=subjectOnlineDataMap.values();
        List<OnlineData> subjectOnlineDataList=new ArrayList<>(subjectOnlineDataCollection);
        Collections.sort(subjectOnlineDataList, new Comparator<OnlineData>() {
            @Override
            public int compare(OnlineData o1, OnlineData o2) {
                return o2.getOnlineBranchNum().compareTo(o1.getOnlineBranchNum());
            }
        });
        onlineList.setSubjectOnlineData(subjectOnlineDataList);

        return onlineList;
    }

    @Override
    public SXSSFWorkbook exportOnlineList(Long areaTeamId, List<Long> periodIds, PeriodQueryRegVo periodQueryRegVo) {
        OnlineList onlineList=this.findOnlineList(areaTeamId,periodIds,periodQueryRegVo);
        return onlineList2excel(onlineList);
    }

    public static SXSSFWorkbook onlineList2excel(OnlineList onlineList) {

        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet busTeamSheet = excel.createSheet("业务组");
        SXSSFRow busTeamFirstRow = busTeamSheet.createRow(0);
        String[] busTeamTitles = new String[]{ "区域","业务组", "总科数", "网报科数","网报科数占比"};
        for (int i = 0; i < busTeamTitles.length; i++) {
            busTeamFirstRow.createCell(i).setCellValue(busTeamTitles[i]);
        }


        SXSSFSheet gradeSheet = excel.createSheet("年级");
        SXSSFRow gradeFirstRow = gradeSheet.createRow(0);
        String[] gradeTitles = new String[]{ "区域","年级", "总科数", "网报科数","网报科数占比"};
        for (int i = 0; i < gradeTitles.length; i++) {
            gradeFirstRow.createCell(i).setCellValue(gradeTitles[i]);
        }

        SXSSFSheet subjectSheet = excel.createSheet("科目");
        SXSSFRow subjectFirstRow = subjectSheet.createRow(0);
        String[] subjectTitles = new String[]{ "区域","科目", "总科数", "网报科数","网报科数占比"};
        for (int i = 0; i < subjectTitles.length; i++) {
            subjectFirstRow.createCell(i).setCellValue(subjectTitles[i]);
        }
        if (onlineList!=null){
            onlineData2Sheet(busTeamSheet,onlineList.getBusTeamOnlineData(),"busTeam");
            onlineData2Sheet(gradeSheet,onlineList.getGradeOnlineData(),"grade");
            onlineData2Sheet(subjectSheet,onlineList.getSubjectOnlineData(),"subject");
        }


        return excel;
    }

    private  static  void onlineData2Sheet( SXSSFSheet sheet,List<OnlineData> onlineDataList,String key){
        int rowNum = 1;
        if (onlineDataList!=null){
            for (OnlineData onlineData : onlineDataList) {
                int cellNum = 0;
                String name="";
                if ("busTeam".equals(key)){
                    name=onlineData.getBusTeamName();
                }else if ("grade".equals(key)){
                    name=onlineData.getGradeName();
                }else if ("subject".equals(key)){
                    name=onlineData.getSubjectName();
                }
                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell  cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(onlineData.getAreaTeamName()));


                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(name));

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(onlineData.getTotalBranchNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(onlineData.getOnlineBranchNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(Utils.getPercent(onlineData.getOnlineBranchNum().toString(),onlineData.getTotalBranchNum().toString(),2));
            }
        }
    }

    @Override
    public Page<StudentRefundDetailVo> findStudentRefundBonusPersonPage(StudentRefundQueryVo studentRefundQueryVo, DataPermission dataPermission, int pageNo, int pageSize) {
        if (studentRefundQueryVo.getAreaTeamId()==null){
            throw new BusException("区域必选");
        }
        studentRefundQueryVo.setStatus(1);
        AreaTeam areaTeam=areaTeamService.findById(studentRefundQueryVo.getAreaTeamId());
        Map<Long,BusTeam> busTeamMap=busTeamService.findBusTeamMapByAreaTeamId(areaTeam.getAreaTeamId());
        Page<StudentRefund> page=studentRefundService.findStudentRefundList(studentRefundQueryVo,dataPermission,pageNo,pageSize);
        Page<StudentRefundDetailVo> studentRefundDetailVoPage=Utils.newPage(page);
        List<StudentRefund> studentRefundList=page.getRecords();
        if (studentRefundList!=null){
            List<Long> studentIds = BeanUtils.toList(studentRefundList, "studentId");
            List<Long> classIds=BeanUtils.toList(studentRefundList,"classId");
            List<Long> studentRefundIds=BeanUtils.toList(studentRefundList,"studentRefundId");
            List<StudentRefundDetailVo> studentRefundDetailVoList=new ArrayList<>(studentRefundList.size());
            List<RefundBonusPerson> refundBonusPersonList=refundBonusPersonService.findByIds(studentRefundIds);
            Map<Long, RefundBonusPerson> studentRefundMap = BeanUtils.toMap(refundBonusPersonList, "studentRefundId");
            List<String> bonusPersonIds = BeanUtils.toList(refundBonusPersonList, "bonusPersonIds");
            bonusPersonIds=bonusPersonIds.stream().filter(item->StringUtils.isNotEmpty(item)).collect(Collectors.toList());

            List<Long> teacherIds=Utils.toArrayLongIds(StringUtils.join(bonusPersonIds,","));



            List<CourseClass> courseClassList=courseClassService.findByIds(classIds,"classId","className","lectureAmount");
            Map<Long, CourseClass> classMap = BeanUtils.toMap(courseClassList, "classId");
            List<MergeStudentRegDetail> mergeStudentRegDetailList=mergeStudentRegDetailService.findByStudentIdsClassIds(studentIds,classIds);

            List<String> bonusClassIdStr = BeanUtils.toList(mergeStudentRegDetailList, "bonusClassIds");
            bonusClassIdStr=bonusClassIdStr.stream().filter(item->StringUtils.isNotEmpty(item)).collect(Collectors.toList());
            List<Long> bonusClassIds = Utils.toArrayLongIds(StringUtils.join(bonusClassIdStr, ","));
            List<CourseClass> bonusCourseClasses=courseClassService.findByIds(bonusClassIds,"classId","teacherId");
            Map<Long, CourseClass> bonusClassMap = BeanUtils.toMap(bonusCourseClasses, "classId");
            List<Long> bonusTeacherIds = BeanUtils.toList(bonusCourseClasses, "teacherId");
            teacherIds.addAll(bonusTeacherIds);

            for (MergeStudentRegDetail mergeStudentRegDetail:mergeStudentRegDetailList){
                if(StringUtils.isNotEmpty(mergeStudentRegDetail.getBonusPeriodPersonIds())){
                    String[] bonusPeriodPersonIds=mergeStudentRegDetail.getBonusPeriodPersonIds().split(",");
                    for (String periodPersonId:bonusPeriodPersonIds){
                        teacherIds.add(Long.parseLong(periodPersonId.split("_")[1]));
                    }
                }
            }
            List<Teacher> teacherList=teacherService.findByIds(Utils.removeDuplicate(teacherIds),"teacherId","teacherName");
            Map<Long,Teacher> teacherMap=BeanUtils.toMap(teacherList,"teacherId");
            Map<String,MergeStudentRegDetail> map=new HashMap<>();
            for (MergeStudentRegDetail mergeStudentRegDetail:mergeStudentRegDetailList){
                String key=mergeStudentRegDetail.getClassId()+"_"+mergeStudentRegDetail.getStudentId();
                map.put(key,mergeStudentRegDetail);
            }
            for (StudentRefund studentRefund:studentRefundList){
                String key=studentRefund.getClassId()+"_"+studentRefund.getStudentId();
                CourseClass courseClass=classMap.get(studentRefund.getClassId());
                RefundBonusPerson refundBonusPerson=studentRefundMap.get(studentRefund.getStudentRefundId());

                MergeStudentRegDetail mergeStudentRegDetail=map.get(key);
                if (mergeStudentRegDetail==null){
                    continue;
                }
                StudentRefundDetailVo studentRefundDetailVo=new StudentRefundDetailVo();
                BeanUtils.copyProperties(studentRefundDetailVo,studentRefund);
                studentRefundDetailVo.setAreaTeamName(areaTeam.getName());
                studentRefundDetailVo.setLectureAmount(courseClass.getLectureAmount());
                studentRefundDetailVo.setFirstPayTime(mergeStudentRegDetail.getFirstPayTime());
                studentRefundDetailVo.setBusTeamName(busTeamMap.get(studentRefund.getBusTeamId()).getName());
                if (refundBonusPerson!=null){
                    studentRefundDetailVo.setBonusSeniorIds(refundBonusPerson.getBonusSeniorIds());
                    if (StringUtils.isNotEmpty(refundBonusPerson.getBonusSeniorIds())){
                        List<String> seniorIds=Utils.toStringList(refundBonusPerson.getBonusSeniorIds());
                        List<String> seniorNames=new ArrayList<>(seniorIds.size());
                        for (String seniorId:seniorIds){
                            Teacher teacher=teacherMap.get(Long.parseLong(seniorId));
                            if (teacher!=null){
                                seniorNames.add(teacher.getTeacherName());
                            }

                        }
                        studentRefundDetailVo.setBonusSeniorNames(StringUtils.join(seniorNames));
                    }
                    if (StringUtils.isNotEmpty(refundBonusPerson.getBonusTeacherIds())){
                        List<String> refundBonusTeacherIds=Utils.toStringList(refundBonusPerson.getBonusTeacherIds());
                        List<String> refundBonusTeacherNames=new ArrayList<>(refundBonusTeacherIds.size());
                        for (String teacherId:refundBonusTeacherIds){
                            refundBonusTeacherNames.add(teacherMap.get(Long.parseLong(teacherId)).getTeacherName());
                        }
                        studentRefundDetailVo.setBonusTeacherNames(StringUtils.join(refundBonusTeacherNames));
                    }
                    studentRefundDetailVo.setBonusPersonLock(1);
                }else {
                    studentRefundDetailVo.setBonusPersonLock(0);
                    if (StringUtils.isNotEmpty(mergeStudentRegDetail.getBonusPeriodPersonIds())){
                        String[] bonusPeriodPersonIds=mergeStudentRegDetail.getBonusPeriodPersonIds().split(",");
                        List<String> personIds=new ArrayList<>(bonusPeriodPersonIds.length);
                        List<String> personNames=new ArrayList<>(bonusPeriodPersonIds.length);
                        for (String periodPersonId:bonusPeriodPersonIds){
                            String personId=periodPersonId.split("_")[1];
                            personIds.add(personId);
                            Teacher teacher=teacherMap.get(Long.parseLong(personId));
                            if (teacher!=null){
                                personNames.add(teacher.getTeacherName());
                            }
                        }
                        studentRefundDetailVo.setBonusSeniorIds(StringUtils.join(personIds,","));
                        studentRefundDetailVo.setBonusSeniorNames(StringUtils.join(personNames,","));
                    }
                    if (StringUtils.isNotEmpty(mergeStudentRegDetail.getBonusClassIds())){
                        List<Long> refundBonusClassIds=Utils.toArrayLongIds(mergeStudentRegDetail.getBonusClassIds());
                        List<Long> refundTeacherIds=new ArrayList<>(refundBonusClassIds.size());
                        List<String> refundTeacherNames=new ArrayList<>(refundBonusClassIds.size());
                        for (Long classId:refundBonusClassIds){
                            CourseClass bonusClass=bonusClassMap.get(classId);
                            if (bonusClass!=null && bonusClass.getTeacherId()!=null){
                                refundTeacherIds.add(bonusClass.getTeacherId());
                                refundTeacherNames.add(teacherMap.get(bonusClass.getTeacherId()).getTeacherName());
                            }
                        }
                        studentRefundDetailVo.setBonusTeacherIds(StringUtils.join(refundTeacherIds,","));
                        studentRefundDetailVo.setBonusTeacherNames(StringUtils.join(refundTeacherNames,","));
                    }
                }
                studentRefundDetailVoList.add(studentRefundDetailVo);

            }
            studentRefundDetailVoPage.setRecords(studentRefundDetailVoList);
        }

        return studentRefundDetailVoPage;
    }

    @Override
    public SXSSFWorkbook exportStudentRefundBonusPerson(StudentRefundQueryVo studentRefundQueryVo, DataPermission dataPermission) {
        Page<StudentRefundDetailVo> page=this.findStudentRefundBonusPersonPage(studentRefundQueryVo,dataPermission,1,50000);
        return studentRefundBonusPerson2Excel(page.getRecords());
    }

    private static SXSSFWorkbook studentRefundBonusPerson2Excel(List<StudentRefundDetailVo> studentRefundDetailVoList){
        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("退费扣除表");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"学生姓名","班级名称","年级","科目","期数","区域","业务组","缴费时间","申请时间","审核时间","班级总讲次","退费开始讲次","提成者(班主任)","任课老师"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        for (StudentRefundDetailVo studentRefundDetailVo:studentRefundDetailVoList){
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getStudentName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getClassName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getGradeName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getSubjectName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getPeriodName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getAreaTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getBusTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getFirstPayTime()==null?"":Utils.formatDate(studentRefundDetailVo.getFirstPayTime(),"yyyy-MM-dd HH:mm:ss"));

            cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getAuditTime()==null?"":Utils.formatDate(studentRefundDetailVo.getAuditTime(),"yyyy-MM-dd HH:mm:ss"));


            cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getLectureAmount()==null?"":studentRefundDetailVo.getLectureAmount().toString());

            cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getRefundLecture().split(",")[0]);

            cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getBonusSeniorNames());

            cell = row.createCell(cellNum++);
            cell.setCellValue(studentRefundDetailVo.getBonusTeacherNames());

        }
        return excel;
    }
    @Override
    public PerimissionTypeListVo checkAndFillDataPerssion(DataPermission dataPermission,Long areaTeamId,List<Long> busTeamIds, List<Long> gradeIds, List<Long> subjectIds) {
        PerimissionTypeListVo perimissionTypeListVo=new PerimissionTypeListVo();

        if (dataPermission==null){
            perimissionTypeListVo.setBusTeamIds(busTeamIds);
            perimissionTypeListVo.setGradeIds(gradeIds);
            perimissionTypeListVo.setSubjectIds(subjectIds);
            return perimissionTypeListVo;
        }
        Principals.Principal principal=Principals.get();
        List<Long> permissionBusTeamIds=dataStatisticsService.findPermissionBusTeam(Arrays.asList(areaTeamId),principal.id);
        List<Long> permissionGradeIds=dataPermission.getGradeIds();
        List<Long> permissionSubjectIds=dataPermission.getSubjectIds();
        if (Utils.isEmpty(permissionBusTeamIds) || Utils.isEmpty(permissionGradeIds) || Utils.isEmpty(permissionSubjectIds)){
            throw new BusException("缺少相应的数据权限");
        }
        if (Utils.isEmpty(busTeamIds)){
            busTeamIds=permissionBusTeamIds;
        }else {
            busTeamIds.retainAll(permissionBusTeamIds);
        }


        if (Utils.isEmpty(gradeIds)){
            gradeIds=permissionGradeIds;
        }else {
            gradeIds.retainAll(permissionGradeIds);
        }


        if (Utils.isEmpty(subjectIds)){
            subjectIds=permissionSubjectIds;
        }else {
            subjectIds.retainAll(permissionSubjectIds);
        }

        if (Utils.isEmpty(busTeamIds) || Utils.isEmpty(gradeIds) || Utils.isEmpty(subjectIds)){
            throw new BusException("缺少相应的数据权限");
        }

        perimissionTypeListVo.setBusTeamIds(busTeamIds);
        perimissionTypeListVo.setGradeIds(gradeIds);
        perimissionTypeListVo.setSubjectIds(subjectIds);
        return perimissionTypeListVo;
    }

    @Override
    public List<PeriodSubjectContinueVo> findPeriodSubjectContinue(Long areaTeamId,Long periodId, DataPermission dataPermission){
        CourseClassQueryVo courseClassQueryVo=new CourseClassQueryVo();
        courseClassQueryVo.setAreaTeamId(areaTeamId);
        RegRelativceQueryVo regRelativceQueryVo=new RegRelativceQueryVo();
        Page<ClassComletionRateVo> page=this.findClassComletionRateVoPage(Arrays.asList(periodId),null,null,courseClassQueryVo,dataPermission,1,20000,regRelativceQueryVo);
        return this.rateToPeriodSubjectContinue(page.getRecords());
    }

    @Override
    public List<PeriodSubjectTeacherContinueVo> findPeriodSubjectTeacherContinue(Long areaTeamId, Long periodId, String teacherName, DataPermission dataPermission) {
        CourseClassQueryVo courseClassQueryVo=new CourseClassQueryVo();
        courseClassQueryVo.setAreaTeamId(areaTeamId);
        courseClassQueryVo.setTeacherName(teacherName);
        RegRelativceQueryVo regRelativceQueryVo=new RegRelativceQueryVo();
        Page<ClassComletionRateVo> page=this.findClassComletionRateVoPage(Arrays.asList(periodId),null,null,courseClassQueryVo,dataPermission,1,20000,regRelativceQueryVo);
        return this.rateToPeriodSubjectTeacherContinue(page.getRecords());
    }

    private List<PeriodSubjectContinueVo> rateToPeriodSubjectContinue(List<ClassComletionRateVo> classComletionRateVoList){
        HashMap<String,PeriodSubjectContinueVo> map=new HashMap<>();
        if (Utils.isEmpty(classComletionRateVoList)){
            return Collections.EMPTY_LIST;
        }
        for (ClassComletionRateVo classComletionRateVo:classComletionRateVoList){
            String key=classComletionRateVo.getPeriodId()+"_"+classComletionRateVo.getSubjectId();
            PeriodSubjectContinueVo periodSubjectContinueVo=map.get(key);
            if (periodSubjectContinueVo==null){
                periodSubjectContinueVo=new PeriodSubjectContinueVo();
                periodSubjectContinueVo.setAreaTeamId(classComletionRateVo.getAreaTeamId());
                periodSubjectContinueVo.setAreaTeamName(classComletionRateVo.getAreaTeamName());
                periodSubjectContinueVo.setSubjectId(classComletionRateVo.getSubjectId());
                periodSubjectContinueVo.setSubjectName(classComletionRateVo.getSubjectName());
                map.put(key,periodSubjectContinueVo);
            }
            Long gradeId=classComletionRateVo.getGradeId();
            Integer regNum=classComletionRateVo.getRegNum();
            Integer seqNum=classComletionRateVo.getSequentialPersonNum();
            Integer stepNum=classComletionRateVo.getStepPersonNum();
            periodSubjectContinueVo.setTotalNum(regNum+periodSubjectContinueVo.getTotalNum());
            periodSubjectContinueVo.setSeqNum(seqNum+periodSubjectContinueVo.getSeqNum());
            periodSubjectContinueVo.setStepNum(stepNum+periodSubjectContinueVo.getStepNum());
            if (gradeId.equals(31l)){
                periodSubjectContinueVo.setGradeOneNum(periodSubjectContinueVo.getGradeOneNum()+regNum);
                periodSubjectContinueVo.setGradeOneSeqNum(periodSubjectContinueVo.getGradeOneSeqNum()+seqNum);
                periodSubjectContinueVo.setGradeOneStepNum(periodSubjectContinueVo.getGradeOneStepNum()+stepNum);

            }else if (gradeId.equals(32l)){
                periodSubjectContinueVo.setGradeTwoNum(periodSubjectContinueVo.getGradeTwoNum()+regNum);
                periodSubjectContinueVo.setGradeTwoSeqNum(periodSubjectContinueVo.getGradeTwoSeqNum()+seqNum);
                periodSubjectContinueVo.setGradeTwoStepNum(periodSubjectContinueVo.getGradeTwoStepNum()+stepNum);
            }else if(gradeId.equals(33l)){
                periodSubjectContinueVo.setGradeThreeNum(periodSubjectContinueVo.getGradeThreeNum()+regNum);
                periodSubjectContinueVo.setGradeThreeSeqNum(periodSubjectContinueVo.getGradeThreeSeqNum()+seqNum);
                periodSubjectContinueVo.setGradeThreeStepNum(periodSubjectContinueVo.getGradeThreeStepNum()+stepNum);
            }
        }
        Collection<PeriodSubjectContinueVo> periodSubjectContinueVos=map.values();
        List<PeriodSubjectContinueVo> periodSubjectContinueVoList=new ArrayList<>(periodSubjectContinueVos);
        return periodSubjectContinueVoList;
    }

    private List<PeriodSubjectTeacherContinueVo> rateToPeriodSubjectTeacherContinue(List<ClassComletionRateVo> classComletionRateVoList){
        HashMap<String,PeriodSubjectTeacherContinueVo> map=new HashMap<>();
        if (Utils.isEmpty(classComletionRateVoList)){
            return Collections.EMPTY_LIST;
        }
        for (ClassComletionRateVo classComletionRateVo:classComletionRateVoList){
            if (classComletionRateVo.getTeacherId()==null){
                continue;
            }
            String key=classComletionRateVo.getPeriodId()+"_"+classComletionRateVo.getSubjectId()+"_"+classComletionRateVo.getTeacherId();
            PeriodSubjectTeacherContinueVo periodSubjectTeacherContinueVo=map.get(key);
            if (periodSubjectTeacherContinueVo==null){
                periodSubjectTeacherContinueVo=new PeriodSubjectTeacherContinueVo();
                BeanUtils.copyProperties(periodSubjectTeacherContinueVo,classComletionRateVo);
                map.put(key,periodSubjectTeacherContinueVo);
            }
            Long gradeId=classComletionRateVo.getGradeId();
            Integer regNum=classComletionRateVo.getRegNum();
            Integer seqNum=classComletionRateVo.getSequentialPersonNum();
            Integer stepNum=classComletionRateVo.getStepPersonNum();
            periodSubjectTeacherContinueVo.setTotalNum(regNum+periodSubjectTeacherContinueVo.getTotalNum());
            periodSubjectTeacherContinueVo.setSeqNum(seqNum+periodSubjectTeacherContinueVo.getSeqNum());
            periodSubjectTeacherContinueVo.setStepNum(stepNum+periodSubjectTeacherContinueVo.getStepNum());
            if (gradeId.equals(31l)){
                periodSubjectTeacherContinueVo.setGradeOneNum(periodSubjectTeacherContinueVo.getGradeOneNum()+regNum);
                periodSubjectTeacherContinueVo.setGradeOneSeqNum(periodSubjectTeacherContinueVo.getGradeOneSeqNum()+seqNum);
                periodSubjectTeacherContinueVo.setGradeOneStepNum(periodSubjectTeacherContinueVo.getGradeOneStepNum()+stepNum);

            }else if (gradeId.equals(32l)){
                periodSubjectTeacherContinueVo.setGradeTwoNum(periodSubjectTeacherContinueVo.getGradeTwoNum()+regNum);
                periodSubjectTeacherContinueVo.setGradeTwoSeqNum(periodSubjectTeacherContinueVo.getGradeTwoSeqNum()+seqNum);
                periodSubjectTeacherContinueVo.setGradeTwoStepNum(periodSubjectTeacherContinueVo.getGradeTwoStepNum()+stepNum);
            }else if(gradeId.equals(33l)){
                periodSubjectTeacherContinueVo.setGradeThreeNum(periodSubjectTeacherContinueVo.getGradeThreeNum()+regNum);
                periodSubjectTeacherContinueVo.setGradeThreeSeqNum(periodSubjectTeacherContinueVo.getGradeThreeSeqNum()+seqNum);
                periodSubjectTeacherContinueVo.setGradeThreeStepNum(periodSubjectTeacherContinueVo.getGradeThreeStepNum()+stepNum);
            }
        }
        Collection<PeriodSubjectTeacherContinueVo> periodSubjectTeacherContinueVos=map.values();
        List<PeriodSubjectTeacherContinueVo> periodSubjectTeacherContinueVoList=new ArrayList<>(periodSubjectTeacherContinueVos);
        return periodSubjectTeacherContinueVoList;
    }


    private List<PeriodBusTeamSubjectGradeLevelContinueVo> rateToPeriodBusTeamSubjectGradeLevelContinue(List<ClassComletionRateVo> classComletionRateVoList){
        HashMap<String,PeriodBusTeamSubjectGradeLevelContinueVo> map=new HashMap<>();
        if (Utils.isEmpty(classComletionRateVoList)){
            return Collections.EMPTY_LIST;
        }
        for (ClassComletionRateVo classComletionRateVo:classComletionRateVoList){
            String key=classComletionRateVo.getPeriodId()+"_"+classComletionRateVo.getBusTeamId()+"_"+classComletionRateVo.getSubjectId()+"_"+classComletionRateVo.getGradeId()+"_"+classComletionRateVo.getLevel();
            PeriodBusTeamSubjectGradeLevelContinueVo periodBusTeamSubjectGradeLevelContinueVo=map.get(key);
            if (periodBusTeamSubjectGradeLevelContinueVo==null){
                periodBusTeamSubjectGradeLevelContinueVo=new PeriodBusTeamSubjectGradeLevelContinueVo();
                BeanUtils.copyProperties(periodBusTeamSubjectGradeLevelContinueVo,classComletionRateVo);
                map.put(key,periodBusTeamSubjectGradeLevelContinueVo);
            }
            Integer regNum=classComletionRateVo.getRegNum();
            Integer seqNum=classComletionRateVo.getSequentialPersonNum();
            Integer stepNum=classComletionRateVo.getStepPersonNum();
            periodBusTeamSubjectGradeLevelContinueVo.setTotalNum(regNum+periodBusTeamSubjectGradeLevelContinueVo.getTotalNum());
            periodBusTeamSubjectGradeLevelContinueVo.setSeqNum(seqNum+periodBusTeamSubjectGradeLevelContinueVo.getSeqNum());
            periodBusTeamSubjectGradeLevelContinueVo.setStepNum(stepNum+periodBusTeamSubjectGradeLevelContinueVo.getStepNum());
        }
        Collection<PeriodBusTeamSubjectGradeLevelContinueVo> periodBusTeamSubjectGradeLevelContinueVos=map.values();
        List<PeriodBusTeamSubjectGradeLevelContinueVo> periodBusTeamSubjectGradeLevelContinueVoList=new ArrayList<>(periodBusTeamSubjectGradeLevelContinueVos);
        return periodBusTeamSubjectGradeLevelContinueVoList;

    }

    @Override
    public SXSSFWorkbook exportPeriodSubjectContinue(Long areaTeamId,Long periodId,DataPermission dataPermission) {
        CourseClassQueryVo courseClassQueryVo=new CourseClassQueryVo();
        courseClassQueryVo.setAreaTeamId(areaTeamId);
        RegRelativceQueryVo regRelativceQueryVo=new RegRelativceQueryVo();
        Page<ClassComletionRateVo> page=this.findClassComletionRateVoPage(Arrays.asList(periodId),null,null,courseClassQueryVo,dataPermission,1,20000,regRelativceQueryVo);
        SXSSFWorkbook excel = new SXSSFWorkbook();
        List<PeriodSubjectContinueVo> periodSubjectContinueVoList = this.rateToPeriodSubjectContinue(page.getRecords());
        List<PeriodBusTeamSubjectGradeLevelContinueVo> periodBusTeamSubjectGradeLevelContinueVoList=this.rateToPeriodBusTeamSubjectGradeLevelContinue(page.getRecords());
        excel=periodSubjectContinue2Excel(excel,periodSubjectContinueVoList);
        excel=periodBusTeamSubjectGradeLevel2Excel(excel,periodBusTeamSubjectGradeLevelContinueVoList);
        return excel;
    }

    @Override
    public SXSSFWorkbook exportPeriodSubjectTeacherContinue(Long areaTeamId, Long periodId, String teacherName, DataPermission dataPermission) {
        List<PeriodSubjectTeacherContinueVo> periodSubjectTeacherContinue = this.findPeriodSubjectTeacherContinue(areaTeamId, periodId, teacherName, dataPermission);
        SXSSFWorkbook excel = new SXSSFWorkbook();
        excel=periodSubjectTeacherContinue2Excel(excel,periodSubjectTeacherContinue);
        return excel;
    }

    @Override
    public Page<TeacherTeachDetailVo> findTeacherTeachDetailPage(DataPermission dataPermission,TeacherTeachDetailQueryVo teacherTeachDetailQueryVo, int pageNo, int pageSize) {
        List<Long> subjectIds=new ArrayList<>();
        if (teacherTeachDetailQueryVo.getSubjectId()!=null){
            subjectIds.add(teacherTeachDetailQueryVo.getSubjectId());
        }
        ClassLectureDetailQueryVo classLectureDetailQueryVo=new ClassLectureDetailQueryVo();
        BeanUtils.copyProperties(classLectureDetailQueryVo,teacherTeachDetailQueryVo);
        PerimissionTypeListVo perimissionTypeListVo = this.checkAndFillDataPerssion(dataPermission, teacherTeachDetailQueryVo.getAreaTeamId(), null, null, subjectIds);
        classLectureDetailQueryVo.setBusTeamIds(perimissionTypeListVo.getBusTeamIds());
        classLectureDetailQueryVo.setSubjectIds(perimissionTypeListVo.getSubjectIds());
        classLectureDetailQueryVo.setGradeIds(perimissionTypeListVo.getGradeIds());
        classLectureDetailQueryVo.setStatuses(Arrays.asList(0,1,3));
        Page<TeacherSubjectSituationVo> teacherSubjectSituationVoPage=classLectureDetailService.findTeacherSubjectDetailPage(classLectureDetailQueryVo,pageNo,pageSize);


        Map<Long,BaseSubject> baseSubjectMap=baseSubjectService.findSubjectMap();
        AreaTeam areaTeam=areaTeamService.findById(teacherTeachDetailQueryVo.getAreaTeamId());
        Period period=periodService.findById(teacherTeachDetailQueryVo.getPeriodId());

        Page<TeacherTeachDetailVo> teachDetailVoPage=Utils.newPage(teacherSubjectSituationVoPage);

        List<TeacherSubjectSituationVo> teacherSubjectSituationVoList=teacherSubjectSituationVoPage.getRecords();


        if (!Utils.isEmpty(teacherSubjectSituationVoList)){
            List<TeacherTeachDetailVo> teacherTeachDetailVoList=new ArrayList<>(teacherSubjectSituationVoList.size());
            List<ClassAmountVo> classAmountVoList=mergeStudentRegDetailService.findClassAmountByPeriodId(teacherTeachDetailQueryVo.getPeriodId());
            Map<Long, ClassAmountVo> classAmountVoMap = BeanUtils.toMap(classAmountVoList, "classId");
            List<CourseClass> courseClassList=courseClassService.findClassListByAreaTeamIdPeriodId(teacherTeachDetailQueryVo.getAreaTeamId(),teacherTeachDetailQueryVo.getPeriodId(),"classId","lectureAmount","teacherId");
            Map<Long, CourseClass> classMap = BeanUtils.toMap(courseClassList, "classId");
            Map<Long, List<CourseClass>> teacherClassMap = BeanUtils.toGroup(courseClassList, "teacherId");
            List<Long> teacherIds = BeanUtils.toList(teacherSubjectSituationVoList, "teacherId");
            List<Teacher> teacherList=teacherService.findByIds(teacherIds,"teacherId","teacherName","level");
            Map<Long, Teacher> teacherMap = BeanUtils.toMap(teacherList, "teacherId");
            for (TeacherSubjectSituationVo teacherSubjectSituationVo:teacherSubjectSituationVoList){
                TeacherTeachDetailVo teacherTeachDetailVo =new TeacherTeachDetailVo();
                BeanUtils.copyProperties(teacherTeachDetailVo,teacherSubjectSituationVo);
                Teacher teacher=teacherMap.get(teacherTeachDetailVo.getTeacherId());
                List<CourseClass> teacherClassList=teacherClassMap.get(teacherTeachDetailVo.getTeacherId());
                teacherTeachDetailVo.setClassNum(teacherClassList==null?0:teacherClassList.size());
                teacherTeachDetailVo.setLevel(teacher.getLevel());
                teacherTeachDetailVo.setTeacherName(teacher.getTeacherName());
                teacherTeachDetailVo.setSubjectName(baseSubjectMap.get(teacherSubjectSituationVo.getSubjectId()).getSubjectName());
                BigDecimal amount=BigDecimal.ZERO;
                Integer totalClassLectureAmount=0;
                if (StringUtils.isNotEmpty(teacherTeachDetailVo.getClassIds())){
                    List<Long> classIds=Utils.toArrayLongIds(teacherTeachDetailVo.getClassIds());
                    for (Long classId:classIds){
                        ClassAmountVo classAmountVo=classAmountVoMap.get(classId);
                        if (classAmountVo!=null){
                            amount=amount.add(classAmountVo.getAmount());
                        }
                        CourseClass courseClass=classMap.get(classId);
                        if (courseClass!=null){
                            totalClassLectureAmount=totalClassLectureAmount+courseClass.getLectureAmount();
                        }
                    }
                }
                teacherTeachDetailVo.setTotalClassAdvance(amount);
                teacherTeachDetailVo.setTotalClassLectureAmount(totalClassLectureAmount);
                teacherTeachDetailVo.setAreaTeamId(areaTeam.getAreaTeamId());
                teacherTeachDetailVo.setAreaTeamName(areaTeam.getName());
                teacherTeachDetailVo.setPeriodId(period.getPeriodId());
                teacherTeachDetailVo.setPeriodName(period.getPeriodName());
                teacherTeachDetailVoList.add(teacherTeachDetailVo);
                teachDetailVoPage.setRecords(teacherTeachDetailVoList);
            }
        }
        return teachDetailVoPage;
    }

    @Override
    public SXSSFWorkbook exportTeacherTeachDetail(DataPermission dataPermission, TeacherTeachDetailQueryVo teacherTeachDetailQueryVo) {
        Page<TeacherTeachDetailVo> teacherTeachDetailVoPage=this.findTeacherTeachDetailPage(dataPermission,teacherTeachDetailQueryVo,1,20000);
        SXSSFWorkbook excel=new SXSSFWorkbook();
        teacherTeachDetail2Excel(excel,teacherTeachDetailVoPage.getRecords());
        return excel;
    }

    private static SXSSFWorkbook teacherTeachDetail2Excel(SXSSFWorkbook excel, List<TeacherTeachDetailVo> teacherTeachDetailVoList){

        SXSSFSheet sheet = excel.createSheet("教师任教情况（学科指标）");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"区域","期数","科目","任课老师","星级","班量","任教总讲次","产生营收"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        for (TeacherTeachDetailVo teacherTeachDetailVo:teacherTeachDetailVoList){
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(teacherTeachDetailVo.getAreaTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(teacherTeachDetailVo.getPeriodName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(teacherTeachDetailVo.getSubjectName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(teacherTeachDetailVo.getTeacherName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(teacherTeachDetailVo.getLevel());

            cell = row.createCell(cellNum++);
            cell.setCellValue(teacherTeachDetailVo.getClassNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(teacherTeachDetailVo.getLectureNum());

            cell = row.createCell(cellNum++);
            BigDecimal decimal=BigDecimal.ZERO;
            if (!teacherTeachDetailVo.getTotalClassLectureAmount().equals(0)){
                decimal = teacherTeachDetailVo.getTotalClassAdvance().multiply(new BigDecimal(teacherTeachDetailVo.getLectureNum().toString())).divide(new BigDecimal(teacherTeachDetailVo.getTotalClassLectureAmount().toString()), 2, BigDecimal.ROUND_HALF_UP);
            }
            cell.setCellValue(    decimal.toString());

        }
        return excel;
    }


    private static SXSSFWorkbook periodBusTeamSubjectGradeLevel2Excel(SXSSFWorkbook excel, List<PeriodBusTeamSubjectGradeLevelContinueVo> periodBusTeamSubjectGradeLevelContinueVoList){

        SXSSFSheet sheet = excel.createSheet("学科续读率2");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"区域","期数","科目","业务组","年级","班型","学生总人数","顺期人数","顺期续读率","跨期人数","跨期续读率"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        for (PeriodBusTeamSubjectGradeLevelContinueVo periodBusTeamSubjectGradeLevelContinueVo:periodBusTeamSubjectGradeLevelContinueVoList){
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(periodBusTeamSubjectGradeLevelContinueVo.getAreaTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodBusTeamSubjectGradeLevelContinueVo.getPeriodName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodBusTeamSubjectGradeLevelContinueVo.getSubjectName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodBusTeamSubjectGradeLevelContinueVo.getBusTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(EnumUtils.getName(ClassLevelEnum.values(),periodBusTeamSubjectGradeLevelContinueVo.getLevel()));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodBusTeamSubjectGradeLevelContinueVo.getTotalNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodBusTeamSubjectGradeLevelContinueVo.getSeqNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodBusTeamSubjectGradeLevelContinueVo.getSeqNum().toString(),periodBusTeamSubjectGradeLevelContinueVo.getTotalNum().toString(),2));


            cell = row.createCell(cellNum++);
            cell.setCellValue(periodBusTeamSubjectGradeLevelContinueVo.getStepNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodBusTeamSubjectGradeLevelContinueVo.getStepNum().toString(),periodBusTeamSubjectGradeLevelContinueVo.getTotalNum().toString(),2));

        }
        return excel;
    }


    private static SXSSFWorkbook periodSubjectContinue2Excel( SXSSFWorkbook excel,List<PeriodSubjectContinueVo> periodSubjectContinueVoList){

        SXSSFSheet sheet = excel.createSheet("学科续读率");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"区域","期数","科目","学生总人数","高一总人数","高二总人数","高三总人数","顺期总人数","顺期续读率","跨期总人数","跨期续读率","高一顺期人数","高一顺期续读率","高二顺期人数","高二顺期续读率","高三顺期人数","高三顺期续读率","高一跨期人数","高一跨期续读率","高二跨期人数","高二跨期续读率","高三跨期人数","高三跨期续读率"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        for (PeriodSubjectContinueVo periodSubjectContinueVo:periodSubjectContinueVoList){
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getAreaTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getPeriodName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getSubjectName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getTotalNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getGradeOneNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getGradeTwoNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getGradeThreeNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getSeqNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectContinueVo.getSeqNum().toString(),periodSubjectContinueVo.getTotalNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getStepNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectContinueVo.getStepNum().toString(),periodSubjectContinueVo.getTotalNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getGradeOneSeqNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectContinueVo.getGradeOneSeqNum().toString(),periodSubjectContinueVo.getGradeOneNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getGradeTwoSeqNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectContinueVo.getGradeTwoSeqNum().toString(),periodSubjectContinueVo.getGradeTwoNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getGradeThreeSeqNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectContinueVo.getGradeThreeSeqNum().toString(),periodSubjectContinueVo.getGradeThreeNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getGradeOneStepNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectContinueVo.getGradeOneStepNum().toString(),periodSubjectContinueVo.getGradeOneNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getGradeTwoStepNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectContinueVo.getGradeTwoStepNum().toString(),periodSubjectContinueVo.getGradeTwoNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectContinueVo.getGradeThreeStepNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectContinueVo.getGradeThreeStepNum().toString(),periodSubjectContinueVo.getGradeThreeNum().toString(),2));


        }
        return excel;
    }

    private static SXSSFWorkbook periodSubjectTeacherContinue2Excel( SXSSFWorkbook excel,List<PeriodSubjectTeacherContinueVo> periodSubjectTeacherContinueVoList){

        SXSSFSheet sheet = excel.createSheet("教师续读率学科指标");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{"区域","期数","科目","主讲老师","学生总人数","高一总人数","高二总人数","高三总人数","顺期总人数","顺期续读率","跨期总人数","跨期续读率","高一顺期人数","高一顺期续读率","高二顺期人数","高二顺期续读率","高三顺期人数","高三顺期续读率","高一跨期人数","高一跨期续读率","高二跨期人数","高二跨期续读率","高三跨期人数","高三跨期续读率"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum=1;
        for (PeriodSubjectTeacherContinueVo periodSubjectTeacherContinueVo:periodSubjectTeacherContinueVoList){
            int cellNum = 0;
            SXSSFRow row = sheet.createRow(rowNum++);

            SXSSFCell cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getAreaTeamName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getPeriodName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getSubjectName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getTeacherName());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getTotalNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getGradeOneNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getGradeTwoNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getGradeThreeNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getSeqNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectTeacherContinueVo.getSeqNum().toString(),periodSubjectTeacherContinueVo.getTotalNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getStepNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectTeacherContinueVo.getStepNum().toString(),periodSubjectTeacherContinueVo.getTotalNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getGradeOneSeqNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectTeacherContinueVo.getGradeOneSeqNum().toString(),periodSubjectTeacherContinueVo.getGradeOneNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getGradeTwoSeqNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectTeacherContinueVo.getGradeTwoSeqNum().toString(),periodSubjectTeacherContinueVo.getGradeTwoNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getGradeThreeSeqNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectTeacherContinueVo.getGradeThreeSeqNum().toString(),periodSubjectTeacherContinueVo.getGradeThreeNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getGradeOneStepNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectTeacherContinueVo.getGradeOneStepNum().toString(),periodSubjectTeacherContinueVo.getGradeOneNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getGradeTwoStepNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectTeacherContinueVo.getGradeTwoStepNum().toString(),periodSubjectTeacherContinueVo.getGradeTwoNum().toString(),2));

            cell = row.createCell(cellNum++);
            cell.setCellValue(periodSubjectTeacherContinueVo.getGradeThreeStepNum());

            cell = row.createCell(cellNum++);
            cell.setCellValue(Utils.getPercent(periodSubjectTeacherContinueVo.getGradeThreeStepNum().toString(),periodSubjectTeacherContinueVo.getGradeThreeNum().toString(),2));


        }
        return excel;
    }


}